validates_uniqueness_of :name, :case_sensitive => false
melakukan trik, tapi Anda harus diingat bahwa validates_uniqueness_of
tidak tidak menjamin keunikan jika Anda memiliki beberapa server proses / server (misalnya berjalan Phusion Penumpang, beberapa mongrel, dll) atau server multi-ulir. Itu karena Anda mungkin mendapatkan urutan kejadian ini (urutannya penting):
- Proses A mendapat permintaan untuk membuat pengguna baru dengan nama 'foo'
- Proses B melakukan hal yang sama
- Proses A memvalidasi keunikan 'foo' dengan menanyakan DB apakah nama itu sudah ada dan DB mengatakan nama itu belum ada.
- Proses B melakukan hal yang sama dan mendapat respons yang sama
- Proses A mengirimkan
insert
pernyataan untuk rekor baru dan berhasil
- Jika Anda memiliki batasan database yang memerlukan keunikan untuk bidang itu, Proses B akan mengirimkan
insert
pernyataan untuk rekaman baru dan gagal dengan pengecualian server jelek yang kembali dari adaptor SQL. Jika Anda tidak memiliki batasan database, penyisipan akan berhasil dan Anda sekarang memiliki dua baris dengan 'foo' sebagai namanya.
Lihat juga "Konkurensi dan integritas" di validates_uniqueness_of
dokumentasi Rails.
Dari Ruby on Rails Edisi ke-3 :
... terlepas dari namanya, validates_uniqueness_of tidak benar-benar menjamin bahwa nilai kolom akan unik. Yang bisa dilakukan hanyalah memverifikasi bahwa tidak ada kolom yang memiliki nilai yang sama dengan yang ada di rekaman yang divalidasi pada saat validasi dilakukan. Ada kemungkinan dua rekaman dibuat pada waktu yang sama, masing-masing dengan nilai yang sama untuk kolom yang harus unik, dan untuk kedua rekaman lolos validasi. Cara paling andal untuk menerapkan keunikan adalah dengan batasan tingkat database. "
Lihat juga pengalaman programmer ini dengan validates_uniqueness_of
.
Salah satu cara yang biasa terjadi adalah pengiriman ganda yang tidak disengaja dari halaman web saat membuat akun baru. Ini sulit untuk dipecahkan karena apa yang akan diperoleh kembali oleh pengguna adalah kesalahan kedua (jelek) dan itu akan membuat mereka mengira pendaftaran mereka gagal, padahal pada kenyataannya itu berhasil. Cara terbaik yang saya temukan untuk mencegahnya adalah dengan menggunakan javascript untuk mencoba mencegah pengiriman ganda.