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

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

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

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里面

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