Risposte:
add_index :people, [:firstname, :lastname, :dob], :unique => true
Secondo howmanyofme.com, "Ci sono 46.427 persone di nome John Smith" solo negli Stati Uniti. Sono circa 127 anni. Poiché questo è ben al di sopra della durata media della vita di un essere umano, ciò significa che uno scontro DOB è matematicamente certo.
Tutto quello che sto dicendo è che quella particolare combinazione di campi unici potrebbe portare a estrema frustrazione utente / cliente in futuro.
Prendi in considerazione qualcosa che sia effettivamente unico, come un numero di identificazione nazionale, se appropriato.
(Mi rendo conto di essere in ritardo alla festa con questo, ma potrebbe aiutare i futuri lettori.)
È possibile che si desideri aggiungere un vincolo senza un indice. Questo dipenderà dal database che stai utilizzando. Di seguito è riportato un codice di migrazione di esempio per Postgres. (tracking_number, carrier)è un elenco delle colonne che si desidera utilizzare per il vincolo.
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
Esistono diversi vincoli che è possibile aggiungere. Leggi i documenti
add_indexmetodo. ;)
Ciao Ad esempio puoi aggiungere un indice univoco nella tua migrazione alle colonne
add_index(:accounts, [:branch_id, :party_id], :unique => true)
o separare indici univoci per ogni colonna
Nell'esempio tipico di una tabella di join tra utenti e post:
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
Cercare di creare due record simili genererà un errore del database (Postgres nel mio 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"
ad es. farlo:
Ownership.create!(user_id: user_id, post_id: post_id)
Ownership.create!(user_id: user_id, post_id: post_id)
Esempio eseguibile completamente: https://gist.github.com/Dorian/9d641ca78dad8eb64736173614d97ced
db/schema.rbgenerato: https://gist.github.com/Dorian/a8449287fa62b88463f48da986c1744a
Per completezza e per evitare confusione, ecco 3 modi per fare la stessa cosa:
aggiungere un vincolo univoco denominato a una combinazione di colonne in Rails 5.2+
Supponiamo di avere una tabella Locations appartenente a un inserzionista con colonna reference_code e desideri solo 1 codice di riferimento per inserzionista. quindi desideri aggiungere un vincolo univoco a una combinazione di colonne e denominarlo.
Fare:
rails g migration AddUniquenessConstraintToLocations
E fai sembrare la tua migrazione qualcosa del genere:
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 questa versione a blocchi.
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 questa versione SQL non elaborata
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
Ognuno di questi avrà lo stesso risultato, controlla il tuo schema.rb