Antworten:
add_index :people, [:firstname, :lastname, :dob], :unique => true
Laut howmanyofme.com gibt es allein in den USA "46.427 Menschen namens John Smith". Das sind ungefähr 127 Jahre. Da dies weit über der durchschnittlichen Lebenserwartung eines Menschen liegt, bedeutet dies, dass ein DOB-Konflikt mathematisch sicher ist.
Ich sage nur, dass diese bestimmte Kombination einzigartiger Felder in Zukunft zu extremer Frustration zwischen Benutzern und Kunden führen kann.
Betrachten Sie etwas, das tatsächlich einzigartig ist, wie gegebenenfalls eine nationale Identifikationsnummer.
(Mir ist klar, dass ich mit diesem sehr spät zur Party komme, aber es könnte zukünftigen Lesern helfen.)
Möglicherweise möchten Sie eine Einschränkung ohne Index hinzufügen. Dies hängt davon ab, welche Datenbank Sie verwenden. Unten finden Sie einen Beispiel für einen Migrationscode für Postgres. (tracking_number, carrier)
ist eine Liste der Spalten, die Sie für die Einschränkung verwenden möchten.
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
Es gibt verschiedene Einschränkungen, die Sie hinzufügen können. Lesen Sie die Dokumente
add_index
Methode. ;)
pg_constraint
Tabelle hinzugefügt wird .
Hallo, Sie können den Spalten beispielsweise einen eindeutigen Index für Ihre Migration hinzufügen
add_index(:accounts, [:branch_id, :party_id], :unique => true)
oder separate eindeutige Indizes für jede Spalte
Im typischen Beispiel einer Join-Tabelle zwischen Benutzern und Posts:
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
Der Versuch, zwei ähnliche Datensätze zu erstellen, führt zu einem Datenbankfehler (in meinem Fall 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"
zB das tun:
Ownership.create!(user_id: user_id, post_id: post_id)
Ownership.create!(user_id: user_id, post_id: post_id)
Vollständig ausführbares Beispiel: https://gist.github.com/Dorian/9d641ca78dad8eb64736173614d97ced
db/schema.rb
generiert: https://gist.github.com/Dorian/a8449287fa62b88463f48da986c1744a
Der Vollständigkeit halber und um Verwirrung zu vermeiden, gibt es drei Möglichkeiten, dasselbe zu tun:
Hinzufügen einer benannten eindeutigen Einschränkung zu einer Kombination von Spalten in Rails 5.2+
Angenommen, wir haben eine Standorttabelle, die zu einem Werbetreibenden gehört und die Spalte reference_code enthält, und Sie möchten nur 1 Referenzcode pro Werbetreibendem. Sie möchten also einer Kombination von Spalten eine eindeutige Einschränkung hinzufügen und sie benennen.
Machen:
rails g migration AddUniquenessConstraintToLocations
Und lassen Sie Ihre Migration entweder so aussehen wie diesen einen Liner:
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
ODER diese Blockversion.
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
ODER diese unformatierte SQL-Version
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
Alle diese haben das gleiche Ergebnis, überprüfen Sie Ihre schema.rb