【问题标题】:Rails - how to restrict user from entering more than one record per associationRails - 如何限制用户在每个关联中输入多个记录
【发布时间】:2013-06-04 13:50:01
【问题描述】:

我是 Rails 新手,一直没能找到这方面的东西。

在我的应用中,我有产品、评论和用户。

评论属于_to用户和产品,而用户和产品都“有_很多”评论。

但是,我想限制用户为每个产品输入多个评论(每个产品都是唯一的)。因此,如果用户为某个产品创建评论并尝试为同一产品撰写另一篇评论,他们会被告知他们不被允许但可以编辑他们现有的评论。

我的问题是:我应该在控制器级别执行此操作,还是可以通过验证来执行此操作(这似乎是一个更简单的解决方案)?只是不知道如何处理它。

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    您可以通过模型验证轻松做到这一点,索引也会有所帮助。但是警告,如果您在没有伴随的 ActiveRecord 验证的情况下执行唯一索引,您的保存将静默失败并导致可用性/调试问题。

    应该这样做:

    class Review < ActiveRecord::Base
      validates :user_id, :uniqueness => { :scope => :product_id,
        :message => "Users may only write one review per product." }
    end
    

    如果要添加索引,请在迁移中尝试:

    class AddUniquenessConstraintToReviews < ActiveRecord::Migration
      add_index  :review, [:user_id, :product_id],
        :name => "udx_reviews_on_user_and_product", :unique => true
    end
    

    编辑:作为一名全职的 Rails 开发人员,我仍然经常参考 the ActiveRecord docs 来更新这些东西的语法。你也应该!

    【讨论】:

    • 为了清楚起见,上面的验证在 Review 模型中正确吗?添加唯一索引有什么好处?
    • @Zephyr4434 是的。我刚刚更新了答案以澄清包含我的示例代码的类的名称。
    • @Zephyr4434 如果您有第二个进程写入此表,唯一索引将派上用场。可能的场景是后台作业队列或多个应用服务器。过去,当我有两个工作处理队列同时写入相同的记录时,我被咬过。由于缺乏唯一性索引,我最终得到了两条记录,即使每个单独的 Rails 引擎都在编写同类中唯一的记录。
    • 知道了,非常有帮助,感谢您的回复。我还将定期查看 ActiveRecord 文档以进行复习
    【解决方案2】:

    最好在审查模型中进行验证。可以将以下方法添加到验证中。[假设您已正确设置关联]

    def validate_only_one_review_per_user
      !(@user.products.include? @product)
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-26
      • 1970-01-01
      • 2021-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-05
      相关资源
      最近更新 更多