Да, тази проверка ще изпълни такъв вид заявка и този вид заявка ще направи сканиране на таблица.
Тук всъщност имате няколко проблема:
- Валидирането подлежи на условия на състезание, тъй като логиката не е в базата данни, където й е мястото. Базата данни трябва да отговаря за всички проблеми с целостта на данните, независимо от обичайната идеология на Rails.
- Вашето потвърждаване задейства сканиране на таблици и никой не харесва сканиране на таблици.
Можете да решите и двата проблема с един индекс. Първият проблем се решава чрез използване на уникален индекс в базата данни. Вторият проблем се решава чрез индексиране на резултата от lower(username)
вместо username
.
AFAIK Rails все още не разбира индексите на изрази, така че ще трябва да направите две неща:
-
Превключете от
schema.rb
къмstructure.sql
за да предпазите Rails от забравяне за вашия индекс. Във вашияconfig/application.rb
ще искате да зададете:config.active_record.schema_format = :sql
Ще трябва също да започнете да използвате
db:structure:*
рейк задачи вместоdb:schema:*
задачи. След като преминете къмstructure.sql
, можете да изтриетеdb/schema.rb
тъй като няма да се актуализира или използва повече; също ще искате да започнете да проследяватеdb/structure.sql
в контрола на ревизиите. -
Създайте индекса на ръка, като напишете малко SQL в миграция. Това е лесно:
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
Разбира се, това ще ви остави със специфични за PostgreSQL неща, но това не е причина за безпокойство, тъй като ActiveRecord така или иначе не ви дава полезна преносимост.