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数情况下,数据库将保证该字段的唯一性。