Rails:验证两列的唯一性(一起)

Posted

技术标签:

【中文标题】Rails:验证两列的唯一性(一起)【英文标题】:Rails: validate uniqueness of two columns (together) 【发布时间】:2016-03-29 04:59:53 【问题描述】:

我有一个 Release 模型,其中包含 mediumcountry 列(等等)。不应有 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 在所有值为 mediumanother_medium 的行中的唯一性。

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

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

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

【讨论】:

【参考方案3】:

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

validates_uniqueness_of :medium, scope: :country

有关更多示例,请参阅documentation。

【讨论】:

@DennisBest 它“有效”,但不能防止竞争条件。如果两个客户端同时发出请求,如果在另一个被验证之前没有一个被提交到数据库,那么它们都可以通过验证。您还需要一个数据库唯一约束,如 tompave 的答案。

以上是关于Rails:验证两列的唯一性(一起)的主要内容,如果未能解决你的问题,请参考以下文章

在 Postgresql 中,对两列的组合强制唯一

在 Postgresql 中,对两列的组合强制唯一

两列的唯一索引加上每一列的单独索引?

PostGreSql 使用拥有 Max 子句获取两列的唯一组合

MS Access 2010 排名查询比较两列的唯一排名

rails 3验证多个属性的唯一性