Réponses:
add_index :people, [:firstname, :lastname, :dob], :unique => true
Selon howmanyofme.com, "Il y a 46 427 personnes nommées John Smith" rien qu'aux États-Unis. Cela fait environ 127 ans de jours. Comme c'est bien au-dessus de la durée de vie moyenne d'un être humain, cela signifie qu'un conflit DOB est mathématiquement certain.
Tout ce que je dis, c'est que cette combinaison particulière de champs uniques pourrait conduire à une frustration extrême des utilisateurs / clients à l'avenir.
Considérez quelque chose qui est en fait unique, comme un numéro d'identification national, le cas échéant.
(Je me rends compte que je suis très en retard à la fête avec celui-ci, mais cela pourrait aider les futurs lecteurs.)
Vous souhaiterez peut-être ajouter une contrainte sans index. Cela dépendra de la base de données que vous utilisez. Voici un exemple de code de migration pour Postgres. (tracking_number, carrier)
est une liste des colonnes que vous souhaitez utiliser pour la contrainte.
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
Vous pouvez ajouter différentes contraintes. Lire la documentation
add_index
méthode. ;)
pg_constraint
table.
Salut Vous pouvez ajouter un index unique dans votre migration aux colonnes par exemple
add_index(:accounts, [:branch_id, :party_id], :unique => true)
ou des index uniques séparés pour chaque colonne
Dans l'exemple typique d'une table de jointure entre les utilisateurs et les publications:
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
Essayer de créer deux enregistrements similaires générera une erreur de base de données (Postgres dans mon cas):
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"
par exemple faire ça:
Ownership.create!(user_id: user_id, post_id: post_id)
Ownership.create!(user_id: user_id, post_id: post_id)
Exemple entièrement exécutable: https://gist.github.com/Dorian/9d641ca78dad8eb64736173614d97ced
db/schema.rb
généré: https://gist.github.com/Dorian/a8449287fa62b88463f48da986c1744a
Par souci d'exhaustivité et pour éviter toute confusion, voici 3 façons de faire la même chose:
Ajouter une contrainte unique nommée à une combinaison de colonnes dans Rails 5.2+
Supposons que nous ayons une table Emplacements qui appartient à un annonceur et que la colonne référence_code et que vous ne souhaitiez qu'un seul code de référence par annonceur. vous voulez donc ajouter une contrainte unique à une combinaison de colonnes et la nommer.
Faire:
rails g migration AddUniquenessConstraintToLocations
Et donnez à votre migration un aspect similaire à celui-ci:
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
OU cette version de bloc.
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
OU cette version SQL brute
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
Chacun de ceux-ci aura le même résultat, vérifiez votre schema.rb