Ya, validasi itu akan melakukan kueri semacam itu dan kueri semacam itu akan melakukan pemindaian tabel.
Anda sebenarnya memiliki beberapa masalah di sini:
- Validasi tunduk pada kondisi balapan karena logikanya tidak ada di database tempatnya berada. Basis data harus bertanggung jawab atas semua masalah integritas data terlepas dari ideologi Rails yang biasa.
- Validasi Anda memicu pemindaian tabel dan tidak ada yang menyukai pemindaian tabel.
Anda dapat menyelesaikan kedua masalah tersebut dengan satu file index. Masalah pertama diselesaikan dengan menggunakan indeks unik di dalam database. Masalah kedua diselesaikan dengan mengindeks hasil lower(username)
daripada username
.
AFAIK Rails masih belum memahami indeks pada ekspresi sehingga Anda harus melakukan dua hal:
-
Beralih dari
schema.rb
kestructure.sql
agar Rails tidak melupakan file index. Diconfig/application.rb
. Anda Anda ingin menyetel:config.active_record.schema_format = :sql
Anda juga harus mulai menggunakan
db:structure:*
menyapu tugas alih-alihdb:schema:*
tugas. Setelah Anda beralih kestructure.sql
, Anda dapat menghapusdb/schema.rb
karena tidak akan diperbarui atau digunakan lagi; Anda juga ingin mulai melacakdb/structure.sql
dalam kontrol revisi. -
Buat indeks dengan tangan dengan menulis sedikit SQL dalam migrasi. Ini mudah:
def up connection.execute(%q{ create index idx_users_lower_username on users(lower(username)) }) end def down connection.execute(%q{ drop index idx_users_lower_username }) end
Tentu saja ini akan meninggalkan Anda dengan hal-hal khusus PostgreSQL, tetapi itu tidak perlu dikhawatirkan karena ActiveRecord tidak memberi Anda portabilitas yang berguna.