Respuestas:
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 del promedio de vida de un ser humano, esto significa que un choque DOB es matemáticamente seguro.
Todo lo que digo es que esa combinación particular de campos únicos podría conducir a una frustración extrema entre usuarios y clientes 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 este, 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é utilizando. A continuación se muestra 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. Lee los documentos
add_index
método. ;)
pg_constraint
tabla.
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 completamente ejecutable: https://gist.github.com/Dorian/9d641ca78dad8eb64736173614d97ced
db/schema.rb
generado: https://gist.github.com/Dorian/a8449287fa62b88463f48da986c1744a
Por razones de integridad y para evitar confusiones, aquí hay 3 formas de hacer lo mismo:
Agregar una restricción única con nombre a una combinación de columnas en Rails 5.2+
Supongamos que tenemos una tabla de ubicaciones que pertenece a un anunciante y tiene una columna reference_code y solo desea 1 código de referencia por anunciante. entonces desea agregar una restricción única a una combinación de columnas y nombrarla.
Hacer:
rails g migration AddUniquenessConstraintToLocations
Y haga que su migración se parezca a esta línea:
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
O esta versión de bloque.
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
O esta versión de SQL sin formato
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
Cualquiera de estos tendrá el mismo resultado, verifique su schema.rb