Una migración para agregar una restricción única a una combinación de columnas

Lo que necesito es una migración para aplicar una restricción única a una combinación de columnas. es decir, para una tabla de people , una combinación de first_name , last_Name y Dob debe ser única.

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

Según howmanyofme.com, “hay 46.427 personas llamadas John Smith” solo en los Estados Unidos. Eso es alrededor de 127 años de días. Como esto está muy por encima de la esperanza de vida promedio de un ser humano, esto significa que un choque entre DOB es matemáticamente seguro.

Todo lo que digo es que esa combinación particular de campos únicos podría llevar a una frustración extrema de usuario / cliente en el futuro.

Considere algo que sea realmente único, como un número de identificación nacional, si corresponde.

(Me doy cuenta de que llego muy tarde a la fiesta con esta, pero podría ayudar a los futuros lectores).

Es posible que desee agregar una restricción sin un índice. Esto dependerá de la base de datos que estés usando. Debajo hay un código de migración de muestra para Postgres. (tracking_number, carrier) es una lista de las columnas que desea usar para la restricción.

 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 

Hay diferentes restricciones que puede agregar. Lea los documentos

Hola, puede agregar un índice único en su migración a las columnas, por ejemplo

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

o índices únicos separados para cada columna

En el ejemplo típico de una tabla de unión entre usuarios y publicaciones:

 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 

Intentar crear dos registros similares arrojará un error de base de datos (Postgres en mi caso):

 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" 

por ejemplo, haciendo eso

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

Ejemplo totalmente ejecutable: https://gist.github.com/Dorian/9d641ca78dad8eb64736173614d97ced

db/schema.rb generated: https://gist.github.com/Dorian/a8449287fa62b88463f48da986c1744a