Мне нужна миграция, чтобы применить уникальное ограничение к комбинации столбцов. т.е. для people
таблицы, комбинации first_name
, last_Name
и Dob
должен быть уникальным.
ruby-on-rails
database
рангало
источник
источник
Согласно сайту howmanyofme.com, «только в США 46 427 человек по имени Джон Смит». Это примерно 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)
или отдельные уникальные индексы для каждого столбца
источник
Для полноты картины и во избежание путаницы вот 3 способа сделать то же самое:
Добавление именованного ограничения уникальности к комбинации столбцов в Rails 5.2+.
Допустим, у нас есть таблица Locations, которая принадлежит рекламодателю и имеет столбец 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
источник
В типичном примере таблицы соединений между пользователями и сообщениями:
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источник