Rails 如何限制文章的评论个数?

nowherekai · 2015年03月06日 · 最后由 hmilym 回复于 2015年03月09日 · 2085 次阅读

需要限制一篇文章的评论数,我的实现如下:

class Article < ActiveRecord::Base
  has_many :comments
  validates_length_of :comments, :maximum => 3, message: "最多有3个评论"
end

class Comment < ActiveRecord::Base
  belongs_to :article
  after_save :validate_comments_length_of_article

  private
  def validate_comments_length_of_article
    if article.comments.length > 2
      errors.add(:base, "文章最多有3个评论")
      return false
    end
  end
end

这样写有没有问题?还有没有其他更好的办法?

共收到 10 条回复

其实要说问题呢, 最好自建个类 立马测试下
一般情况下 文章下面就是评论区 你可以在这里设置 当有三条评论时 你就把评论区隐藏起来

建议将after_save改为after_create

after_save runs both on create and update, but always after the more specific callbacks after_create and after_update, no matter the order in which the macro calls were executed.

active_record_callbacks

在 article 加个 comments_count 是不是更简单?

  1. 校验应该写成 validation 而不是 callback
  2. 跨模型的逻辑我倾向写在 Controller。

楼主的代码存在以下问题:

  1. Article 类不应该做有关评论个数的 validation,因为 Article 类的对象在创建的时候并不知道底下有多少 comment
  2. Comment 类可以做这种 validation,只是不应该用 callback 的形式,而是应该用自定义 validation 的形式。

下面是我帮你改过后的代码:

class Article < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :article
  validate :validate_comments_length_of_article

  private
  def validate_comments_length_of_article
    if article.comments.length > 2
      errors.add(:base, "文章最多有3个评论")
    end
  end
end

最后提醒一下,即便是做了这种 validation,也不能保证所有 Article 底下的 Comment 就不会超过 3 个。因为在并发的环境下,有可能 N 个请求同时满足 validation 的条件,但是结果就是同时生成了 N 条评论。N>3 的情况下,就无法得到楼主所期望的效果了。

validates_length_of :comments, :maximum => 3, message: "最多有 3 个评论" 震惊了 不过类似这样的需求,一般在 controller 里面好一点

多谢了 是应该用 after_create 而且不用 callback 做 validate

还是写在 controller 里好了,model 里面这样限制容易出问题

用了 #5 楼 @cuterxy 的代码,谢了,其他各位不一一 @ 了

推荐把逻辑写到 controller 里面

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册