Jawaban:
add_index :people, [:firstname, :lastname, :dob], :unique => true
Menurut howmanyofme.com, "Ada 46.427 orang bernama John Smith" di Amerika Serikat saja. Itu sekitar 127 tahun. Karena ini jauh melebihi usia rata-rata manusia, ini berarti bahwa bentrokan DOB secara matematis pasti.
Semua yang saya katakan adalah bahwa kombinasi bidang unik tertentu dapat menyebabkan frustrasi pengguna / pelanggan yang ekstrem di masa depan.
Pertimbangkan sesuatu yang benar-benar unik, seperti nomor identifikasi nasional, jika sesuai.
(Saya sadar bahwa saya sangat terlambat ke pesta dengan pesta ini, tetapi ini bisa membantu pembaca di masa depan.)
Anda mungkin ingin menambahkan batasan tanpa indeks. Ini akan tergantung pada database apa yang Anda gunakan. Di bawah ini adalah contoh kode migrasi untuk Postgres. (tracking_number, carrier)
adalah daftar kolom yang ingin Anda gunakan untuk kendala.
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
Ada beberapa kendala yang dapat Anda tambahkan. Baca dokumen
add_index
metode. ;)
Hai Anda dapat menambahkan indeks unik dalam migrasi Anda ke kolom misalnya
add_index(:accounts, [:branch_id, :party_id], :unique => true)
atau pisahkan indeks unik untuk setiap kolom
Dalam contoh khas tabel gabungan antara pengguna dan pos:
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
Mencoba membuat dua catatan serupa akan membuat kesalahan basis data (Postgres dalam kasus saya):
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"
misalnya melakukan itu:
Ownership.create!(user_id: user_id, post_id: post_id)
Ownership.create!(user_id: user_id, post_id: post_id)
Contoh sepenuhnya dapat dijalankan: https://gist.github.com/Dorian/9d641ca78dad8eb64736173614d97ced
db/schema.rb
dihasilkan: https://gist.github.com/Dorian/a8449287fa62b88463f48da986c1744a
Demi kelengkapan, dan untuk menghindari kebingungan di sini adalah 3 cara melakukan hal yang sama:
Menambahkan kendala unik bernama ke kombinasi kolom di Rails 5.2+
Katakanlah kita memiliki tabel Lokasi yang dimiliki pengiklan dan memiliki kode referensi_kolom dan Anda hanya ingin 1 kode referensi per pengiklan. jadi Anda ingin menambahkan batasan unik ke kombinasi kolom dan beri nama.
Melakukan:
rails g migration AddUniquenessConstraintToLocations
Dan buat migrasi Anda terlihat seperti ini:
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
ATAU versi blok ini.
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
ATAU versi SQL mentah ini
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
Semua ini akan memiliki hasil yang sama, periksa schema.rb