【问题标题】:How to specify "unique" values in Rails 3, PostgreSQL next to existing "unique key"?如何在现有“唯一键”旁边的 Rails 3、PostgreSQL 中指定“唯一”值?
【发布时间】:2012-12-14 18:29:08
【问题描述】:

我现有的 Rails 应用程序是用 Rails 3.2 编写的,并使用 PostgreSQL 作为数据库引擎。我们的产品表包含来自多个网站的产品。目前,每个产品在进入时都会获得一个唯一的 ID。

这是模型:

class Platform < ActiveRecord::Base
  attr_accessible :name, :url, :country, :email
  validates :name, :presence => true, 
        :length => { :minimum => 1 }
  has_many :sectors
end

这个表的数据库模式来自 schema.rb

create_table "platforms", :force => true do |t|
    t.string   "name"
    t.string   "url"
    t.datetime "created_at",                               :null => false
    t.datetime "updated_at",                               :null => false
    t.string   "country"
    t.string   "email"
  end

是否可以使用“URL”参数添加另一个禁止进入或新产品的“唯一键”?我不确定用Rails g migration 实现这样的事情而不破坏现有记录(如果已经存在重复)。

所以基本上:如果新产品的 url 对应于数据库中已有的 url,我希望 rails 禁止添加新产品,类似于如果有产品,我不允许输入 id=1 的产品数据库中已有 id=1。

【问题讨论】:

  • 我不明白您的要求,您希望每个产品都有唯一的 URL 吗?
  • 如果新产品的url对应数据库中已有的url,我希望rails禁止添加新产品,类似于我不允许输入id=1的产品,如果有数据库中已有 id=1 的产品。
  • PostgreSQL 将对您现有的数据强制执行唯一约束,因此如果您已经有重复数据,您将无法添加一个。您必须尝试使用​​ Rails 代码中的验证(但这会让您面临竞争条件)或使用触发器(但 Rails 使这成为一场噩梦)来强制执行您的唯一性。
  • 我建议您使用数据库级别的约束,而不是 Rails 中的某些东西或触发器,因为 1) 这需要您在应用约束之前手动清除重复项。我觉得很奇怪对某些记录有限制,但不是全部,因此为了获得良好的数据完整性,您应该首先修复现有记录。 2)数据库会做得更好,更快,所以让它。此外,还有穆提到的担忧......

标签: ruby-on-rails database postgresql


【解决方案1】:

您可以在模型上执行此操作:

class MyModel < ActiveRecord::Base
  validates_uniqueness_of :url
end

或者(取决于您的数据库,MySQL 的反应可能与 PGsql 不同):

# migration file
t.string :url, :null => false, :unique => true

【讨论】:

  • 如果数据库中已经存在重复项,您将无法添加唯一约束,PostgreSQL(谢天谢地)希望约束对表中的所有内容都为真。并且validates_uniqueness_of 受制于the validations guide 中所述的竞争条件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-03
  • 2013-02-21
  • 1970-01-01
  • 2017-05-04
  • 1970-01-01
相关资源
最近更新 更多