Rails:共同验证两列的唯一性


Answers:


230

您可以在选项中使用唯一性验证scope

另外,您应该向数据库添加唯一索引,以防止新记录在写入之前同时检查时通过验证:

class AddUniqueIndexToReleases < ActiveRecord::Migration
  def change
    add_index :releases, [:country, :medium], unique: true
  end
end



class Release < ActiveRecord::Base
  validates :country, uniqueness: { scope: :medium }
end

索引为+1,但索引为-1,unique因为无法识别。对于那部分,我使用下面的答案。
Aleks

7
是的,很抱歉,验证码应该是uniqueness,而不是unique。请参阅链接的文档。确定答案。
删除

1
嗯,很好,谢谢:)再说一遍-在找到此答案之前,将索引将解决方案带入一个新的高度,而不仅仅是我一直在尝试的其他“编码”解决方案。为此+1
Aleks

70

上面所有的答案都缺少如何验证模型中多个属性的唯一性。下面的代码旨在告诉您如何在作用域中使用多个属性。

validates :country, uniqueness: { scope: [:medium, :another_medium] }

这验证了独特的country与值的所有行mediumanother_medium

注意:不要忘了在上面的列上添加索引,这样可以确保快速检索并为唯一记录添加数据库级别的验证。

更新:用于在创建表时添加索引

t.index [:medium, :another_medium], unique: true

41

您可以:scope像这样将参数传递给验证器:

validates_uniqueness_of :medium, scope: :country

有关更多示例,请参见文档


8
@DennisBest它“有效”,但不能防止比赛条件。如果两个客户端同时发出请求,则在两个客户端都未通过验证之前已提交给数据库的情况下,它们都可以通过验证。如tompave的答案一样,您还需要一个数据库唯一约束。
汤狗
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.