Ruby on rails Rails模型验证-仅创建一条具有特定值的记录

Ruby on rails Rails模型验证-仅创建一条具有特定值的记录,ruby-on-rails,ruby,Ruby On Rails,Ruby,我有评级模型来按用户评估我的功能。当用户单击我的某项功能(例如,数据图表)下的“喜欢”或“不喜欢”按钮时,应创建新的评级记录。评级记录示例:#。我想防止出现如下情况: #<Rating:0x00007f8d839b2630 id: 7, customer_id: 1, actions: 'like', feature_uid: 'data_chart'> #<Rating:0x00007f8d839b2630 id: 8, customer_id: 1, actions: 'd

我有
评级
模型来按用户评估我的功能。当用户单击我的某项功能(例如,
数据图表
)下的“喜欢”或“不喜欢”按钮时,应创建新的评级记录。评级记录示例:
#
。我想防止出现如下情况:

#<Rating:0x00007f8d839b2630 id: 7, customer_id: 1, actions: 'like', feature_uid: 'data_chart'>
#<Rating:0x00007f8d839b2630 id: 8, customer_id: 1, actions: 'dislike', feature_uid: 'data_chart'>

您可以使用验证器防止为现有的
客户id
功能uid
对创建新记录

在您的特定情况下,它将如下所示:

等级
这是


还值得一提的是,唯一性验证器仅在模型级别工作,换句话说,它不会在数据库中创建唯一性约束,因此两个不同的同时数据库连接可能会为您想要唯一的列创建两个具有相同值的记录

为了防止这种情况,您需要在数据库中的一对列上创建一个唯一的索引。例如,有关多个列索引的更多详细信息,或有关引用一组列的唯一约束的示例,请参见


下面是一种使用Rails迁移在多个列上创建唯一索引的方法

  • 创建一个迁移
  • 修改它
  • class AddUniqueIndexForCustomerIdAndFeatureUidToRatings
  • 应用该迁移


  • .

    如果涉及索引唯一索引-在我的例子中,它将类似于
    t.string:feature\u uid,null:false,unique:true
    ?我理解得对吗?该索引意味着每个记录必须有一个唯一的值:feature\u uid,因此在您的情况下,它意味着每个功能只能评级一次!因为如果另一个用户尝试对同一功能进行评分,则会导致重复错误。所以,正如@Marian13所说,您必须在两列(一起)上放置一个索引。。哪些是customer&feature\u uid。@先生,我用一个使用Rails迁移为多列创建唯一索引的示例更新了我的答案。
      def change
        create_table :ratings do |t|
          t.references :customer, null: false, foreign_key: true
          t.string :action, null: false
          t.string :feature_uid, null: false
    
          t.timestamps
        end
      end
    
    class Rating < ApplicationRecord
      belongs_to :customer
    
      validates :feature_uid, inclusion: { in: ['data_chart (...) some_other_features)'] }
      validates :action, inclusion: { in: %w[like dislike] }
    end
    
    $ rails generate migration add_unique_index_for_customer_id_and_feature_uid_to_ratings
    
    $ rails db:migrate