Có, xác thực đó sẽ thực hiện loại truy vấn đó và loại truy vấn đó sẽ thực hiện quét bảng.
Bạn thực sự có một vài vấn đề ở đây:
- Việc xác thực phải tuân theo các điều kiện chủng tộc vì logic không có trong cơ sở dữ liệu nơi nó thuộc về. Cơ sở dữ liệu phải chịu trách nhiệm về tất cả các vấn đề về tính toàn vẹn của dữ liệu bất kể hệ tư tưởng thông thường của Rails.
- Quá trình xác thực của bạn kích hoạt tính năng quét bảng và không ai thích quét bảng.
Bạn có thể giải quyết cả hai vấn đề đó với một chỉ mục. Vấn đề đầu tiên được giải quyết bằng cách sử dụng một chỉ mục duy nhất bên trong cơ sở dữ liệu. Vấn đề thứ hai được giải quyết bằng cách lập chỉ mục kết quả của lower(username)
thay vì username
.
AFAIK Rails vẫn không hiểu các chỉ mục trên các biểu thức, vì vậy bạn sẽ phải làm hai việc:
-
Chuyển từ
schema.rb
thànhstructure.sql
để giữ cho Rails không quên chỉ mục của bạn. Trongconfig/application.rb
của bạn bạn sẽ muốn đặt:config.active_record.schema_format = :sql
Bạn cũng sẽ phải bắt đầu sử dụng
db:structure:*
tác vụ rake thay vìdb:schema:*
các nhiệm vụ. Khi bạn đã chuyển sangstructure.sql
, bạn có thể xóadb/schema.rb
vì nó sẽ không được cập nhật hoặc sử dụng nữa; bạn cũng sẽ muốn bắt đầu theo dõidb/structure.sql
trong kiểm soát sửa đổi. -
Tạo chỉ mục bằng tay bằng cách viết một chút SQL trong quá trình di chuyển. Điều này thật dễ dàng:
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
Tất nhiên điều này sẽ để lại cho bạn những thứ cụ thể về PostgreSQL nhưng điều đó không có gì đáng lo ngại vì dù sao thì ActiveRecord cũng không cung cấp cho bạn bất kỳ tính di động hữu ích nào.