Rails:validation3列的唯一组合

嗨,我不想validation我的表中3列的独特组合。

比方说,我有一个名为汽车的表,其中包括:brand,:model_name和:fuel_type。

然后我想要的是validation,如果一个logging是独特的基础上的组合3例如:

brand model_name fuel_type Audi A4 Gas Audi A4 Diesel Audi A6 Gas 

应该都是有效的。 但另一个logging“奥迪,A6,天然气”应该是无效的。

我知道这个validation,但我怀疑它实际上做我想要的。

  validates_uniqueness_of :brand, :scope => {:model_name, :fuel_type} 

您的代码段中存在语法错误。 正确的validation是:

 validates_uniqueness_of :car_model_name, :scope => [:brand_id, :fuel_type_id] 

在Ruby 1.9.x中甚至更短:

 validates_uniqueness_of :car_model_name, scope: [:brand_id, :fuel_type_id] 

导轨4你可以使用:

 validates :car_model_name, uniqueness: { scope: [:brand_id, :fuel_type_id] } 

您可以使用导轨5

 validates_uniqueness_of :car_model_name, scope: %i[brand_id fuel_type_id] 

取决于你的需求,你也可以添加一个约束(作为表创build迁移的一部分或作为一个单独的),而不是模型validation:

 add_index :the_table_name, [:brand, :model_name, :fuel_type], :unique => true 

在多个数据库连接同时执行写入操作的情况下,在数据库级别添加唯一约束是有意义的。

我会这样做:

 validates_uniqueness_of :model_name, :scope => {:brand_id, :fuel_type_id} 

因为这对我来说更有意义:

  • 对于“品牌”和“燃料types”的组合,不应该重复“型号名称”
  • 对于“型号名称”和“燃料types”的组合,不应该重复“品牌”

但这是主观意见。

当然,如果品牌和fuel_type与其他模型的关系(如果不是,那么只需放下“_id”部分)。 通过唯一性validation,您不能检查非db列,所以您必须validation模型中的外键。

你需要定义哪个属性是有效的 – 你不需要一次validation,如果你想要的话,你需要为每个属性创build单独的validation,所以当用户犯错并尝试创build重复的logging,那么你向他显示错误在无效字段附近形成。

用新的哈希模式引导4正确的代码

 validates :column_name, uniqueness: {scope: [:brand_id, :fuel_type_id]} 

将此validation方法与ActiveRecord::Validations#save一起使用并不能保证不存在重复的logging插入,因为应用程序级别上的唯一性检查本质上容易出现竞争状况。

如果您使用具有“可序列化”隔离级别的事务,则甚至会发生这种情况。 解决此问题的最佳方法是使用ActiveRecord::ConnectionAdapters::SchemaStatements#add_index为数据库表添加唯一索引。 在极less数情况下,数据库将保证该字段的唯一性。