Apakah ada cara rel cara untuk memvalidasi bahwa catatan aktual itu unik dan bukan hanya kolom? Misalnya, model / tabel pertemanan tidak boleh memiliki beberapa catatan identik seperti:
user_id: 10 | friend_id: 20
user_id: 10 | friend_id: 20
Apakah ada cara rel cara untuk memvalidasi bahwa catatan aktual itu unik dan bukan hanya kolom? Misalnya, model / tabel pertemanan tidak boleh memiliki beberapa catatan identik seperti:
user_id: 10 | friend_id: 20
user_id: 10 | friend_id: 20
Is there a rails-way way
. Dan Anda menawarkan cara non-rel, tapi standar.The Active Record way claims that intelligence belongs in your models, not in the database.
validates :field_name, unique: true
rentan terhadap kondisi balapan, jadi meskipun melawan jalur rel, kendala yang sebenarnya lebih disukai. @ HarryJoy Saya akan menjawab dengan jawaban yang menjelaskan cara kendala.Jawaban:
Anda dapat mengatur
validates_uniqueness_of
panggilan sebagai berikut.sumber
validates_uniqueness_of [:user_id, :friend_id]
. Mungkin ini perlu ditambal?Anda dapat menggunakan
validates
untuk memvalidasiuniqueness
pada satu kolom:Sintaks untuk validasi pada beberapa kolom serupa, tetapi Anda harus menyediakan array bidang sebagai gantinya:
Namun , pendekatan validasi yang ditunjukkan di atas memiliki kondisi balapan dan tidak dapat memastikan konsistensi. Perhatikan contoh berikut:
catatan tabel database seharusnya unik oleh n bidang;
beberapa ( dua atau lebih ) permintaan bersamaan, masing-masing ditangani oleh proses yang terpisah ( server aplikasi, server pekerja latar belakang atau apa pun yang Anda gunakan ), mengakses database untuk menyisipkan catatan yang sama dalam tabel;
setiap proses secara paralel memvalidasi jika ada catatan dengan bidang n yang sama ;
validasi untuk setiap permintaan berhasil dilewati, dan setiap proses membuat catatan dalam tabel dengan data yang sama.
Untuk menghindari perilaku semacam ini, kita harus menambahkan batasan unik ke tabel db. Anda dapat mengaturnya dengan
add_index
helper untuk satu (atau beberapa) bidang dengan menjalankan migrasi berikut:Peringatan : bahkan setelah Anda menetapkan batasan unik, dua atau lebih permintaan bersamaan akan mencoba untuk menulis data yang sama ke db, tetapi alih-alih membuat rekaman duplikat, ini akan menimbulkan
ActiveRecord::RecordNotUnique
pengecualian, yang harus Anda tangani secara terpisah:sumber
Ini dapat dilakukan dengan batasan basis data pada dua kolom:
add_index :friendships, [:user_id, :friend_id], unique: true
Anda bisa menggunakan validator rel, tetapi secara umum saya sarankan menggunakan batasan database.
Lebih banyak membaca: https://robots.thoughtbot.com/validation-database-constraint-or-both
sumber