Rails:验证两列的唯一性(一起)
Posted
技术标签:
【中文标题】Rails:验证两列的唯一性(一起)【英文标题】:Rails: validate uniqueness of two columns (together) 【发布时间】:2016-03-29 04:59:53 【问题描述】:我有一个 Release
模型,其中包含 medium
和 country
列(等等)。不应有 releases
共享相同的 medium
/country
组合。
如何将其编写为 Rails 验证?
【问题讨论】:
Rails: Validate uniqueness of multiple columns的可能重复 【参考方案1】:您可以将uniqueness 验证与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
,因为它无法识别。对于那部分,我使用了下面的答案。
是的,抱歉,验证密钥应该是uniqueness
,而不是unique
。请参阅链接的文档。确定答案。
嗯,很好,谢谢 :) 再说一遍——在找到这个答案之前,将索引放到一个新的水平,而不是像我遇到的其他“编码”解决方案一样.为此 +1
“传递”一个数组到scope:
以检查两个以上字段的唯一性。【参考方案2】:
以上所有答案都缺少如何验证模型中多个属性的唯一性。下面的代码旨在说明如何在一个范围内使用多个属性。
validates :country, uniqueness: scope: [:medium, :another_medium]
它验证 country
在所有值为 medium
和 another_medium
的行中的唯一性。
注意:不要忘记在上面的列上添加索引,这样可以确保快速检索并为唯一记录添加数据库级别的验证。
更新:用于在创建表时添加索引
t.index [:medium, :another_medium], unique: true
【讨论】:
【参考方案3】:您可以像这样将:scope
参数传递给您的验证器:
validates_uniqueness_of :medium, scope: :country
有关更多示例,请参阅documentation。
【讨论】:
@DennisBest 它“有效”,但不能防止竞争条件。如果两个客户端同时发出请求,如果在另一个被验证之前没有一个被提交到数据库,那么它们都可以通过验证。您还需要一个数据库唯一约束,如 tompave 的答案。以上是关于Rails:验证两列的唯一性(一起)的主要内容,如果未能解决你的问题,请参考以下文章