用于向列组合添加唯一约束的迁移

时间:2010-07-30 09:36:39

标签: ruby-on-rails database

我需要的是将唯一约束应用于列组合的迁移。对于people表格,first_namelast_NameDob的组合应该是唯一的。

6 个答案:

答案 0 :(得分:225)

add_index :people, [:firstname, :lastname, :dob], :unique => true

答案 1 :(得分:21)

据howmanyofme.com报道,“仅在美国就有46,427人名叫约翰史密斯”。那是大约127年的日子。由于这远远超过了人类的平均寿命,这意味着DOB冲突在数学上是确定的。

我只是说,独特字段的特殊组合可能会导致用户/客户极度受挫。

考虑一些实际上唯一的东西,如果合适的话,就像国家识别码一样。

(我意识到我参加派对很晚,但它可以帮助未来的读者。)

答案 2 :(得分:17)

您可能希望添加没有索引的约束。这取决于您使用的数据库。以下是Postgres的示例迁移代码。 (tracking_number, carrier)是您要用于约束的列的列表。

class AddUniqeConstraintToShipments < ActiveRecord::Migration
  def up
    execute <<-SQL
      alter table shipments
        add constraint shipment_tracking_number unique (tracking_number, carrier);
    SQL
  end

  def down
    execute <<-SQL
      alter table shipments
        drop constraint if exists shipment_tracking_number;
    SQL
  end
end

您可以添加不同的约束。 Read the docs

答案 3 :(得分:7)

您好您可以在迁移到列中添加唯一索引,例如

add_index(:accounts, [:branch_id, :party_id], :unique => true)

或为每列分开唯一索引

答案 4 :(得分:3)

在用户和帖子之间的连接表的典型示例中:

create_table :users
create_table :posts

create_table :ownerships do |t|
  t.belongs_to :user, foreign_key: true, null: false
  t.belongs_to :post, foreign_key: true, null: false
end

add_index :ownerships, [:user_id, :post_id], unique: true

尝试创建两个类似的记录会引发数据库错误(在我的情况下是Postgres):

ActiveRecord::RecordNotUnique: PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "index_ownerships_on_user_id_and_post_id"
DETAIL:  Key (user_id, post_id)=(1, 1) already exists.
: INSERT INTO "ownerships" ("user_id", "post_id") VALUES ($1, $2) RETURNING "id"

e.g。这样做:

Ownership.create!(user_id: user_id, post_id: post_id)
Ownership.create!(user_id: user_id, post_id: post_id)

完全可运行的示例:https://gist.github.com/Dorian/9d641ca78dad8eb64736173614d97ced

db/schema.rb已生成:https://gist.github.com/Dorian/a8449287fa62b88463f48da986c1744a

答案 5 :(得分:1)

出于完整性考虑,为了避免混淆,这里有三种做同一件事的方法:
在Rails 5.2+中的列组合中添加命名的唯一约束

比方说,我们有一个属于广告客户的“位置”表,该表具有reference_code列,您每个广告客户只需要1个参考代码。因此您想向列组合添加唯一约束并命名。

要做:

rails g migration AddUniquenessConstraintToLocations

并使您的迁移看起来像这样的一种衬里:

class AddUniquenessConstraintToLocations < ActiveRecord::Migration[5.2]
  def change
    add_index :locations, [:reference_code, :advertiser_id], unique: true, name: 'uniq_reference_code_per_advertiser'
  end
end

或此阻止版本。

class AddUniquenessConstraintToLocations < ActiveRecord::Migration[5.2]
  def change
    change_table :locations do |t|
     t.index ['reference_code', 'advertiser_id'], name: 'uniq_reference_code_per_advertiser', unique: true
    end
  end
end

或此原始SQL版本

class AddUniquenessConstraintToLocations < ActiveRecord::Migration[5.2]
  def change
      execute <<-SQL
          ALTER TABLE locations
            ADD CONSTRAINT uniq_reference_code_per_advertiser UNIQUE (reference_code, advertiser_id);
        SQL
  end
end

其中任何一个都会得到相同的结果,请检查您的schema.rb