A migration to add unique constraint to a combination of columns
我需要进行的是将唯一约束应用于列组合的迁移。 即对于
根据howmanyofme.com,仅在美国就有" 46,427名叫约翰·史密斯的人"。那大约是127年的日子。由于这已经超过了人类的平均寿命,因此这意味着DOB冲突在数学上是确定的。
我要说的是,独特字段的特定组合将来可能会导致极大的用户/客户挫败感。
如果合适的话,考虑一下实际上是唯一的东西,例如国家识别号。
(我意识到我参加这一晚会很晚,但是它可以帮助将来的读者。)
您可能想要添加没有索引的约束。这将取决于您使用的数据库。以下是Postgres的示例迁移代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 |
您可以添加不同的约束。阅读文档
您好,例如,您可以在迁移中向列添加唯一索引
1 | add_index(:accounts, [:branch_id, :party_id], :unique => true) |
或为每列单独的唯一索引
为了完整起见,并且为了避免混淆,这里提供了三种执行同一操作的方法:
在Rails 5.2+中向列的组合添加命名的唯一约束
假设我们有一个属于广告客户的Locations表,并且具有reference_code列,而每个广告客户只需要1个参考代码。因此,您想向列组合添加唯一约束并命名。
做:
并使您的迁移看起来像这样的一种衬板:
1 2 3 4 5 | 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 |
或此块版本。
1 2 3 4 5 6 7 | 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版本
1 2 3 4 5 6 7 8 | 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 |
这些中的任何一个都将具有相同的结果,请检查您的
在用户和帖子之间的联接表的典型示例中:
1 2 3 4 5 6 7 8 9 | 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):
1 2 3 | 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" |
例如这样做:
1 2 | 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