Відповіді:
add_index :people, [:firstname, :lastname, :dob], :unique => true
За даними howmanyofme.com, "лише в США 46 467 людей на ім'я Джон Сміт". Це приблизно 127 років. Оскільки це значно за середній термін життя людини, це означає, що зіткнення DOB є математично визначеним.
Все, що я говорю, полягає в тому, що саме ця комбінація унікальних полів може призвести до сильних розладів користувачів / клієнтів у майбутньому.
Розгляньте щось, що насправді є унікальним, як, наприклад, національний ідентифікаційний номер.
(Я усвідомлюю, що я дуже спізнюся на вечірку з цим, але це може допомогти майбутнім читачам.)
Ви можете додати обмеження без індексу. Це залежатиме від того, яку базу даних ви використовуєте. Нижче наведено зразок коду міграції для 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
Ви можете додати різні обмеження. Прочитайте документи
add_indexметоду. ;)
pg_constraintтаблиці.
Привіт Ви можете додавати унікальний індекс при міграції, наприклад, у стовпці
add_index(:accounts, [:branch_id, :party_id], :unique => true)
або окремі унікальні індекси для кожного стовпця
У типовому прикладі таблиці з'єднання між користувачами та публікаціями:
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"
наприклад, роблячи це:
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
Для повноти та щоб уникнути плутанини, ось три способи зробити те саме:
Додавання названого унікального обмеження до комбінації стовпців у Rails 5.2+
Скажімо, у нас є таблиця "Місцеположення", яка належить рекламодавцю і має код коду стовпця, і вам потрібно лише 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