Ответ 1
result = Users.find(:all, :order => "LOWER(name)")
Немного от Брэда и Фрэнка.
В процессе переключения моей среды разработки от sqlite3 до postgresql 8.4 и последнего препятствия.
В моем оригинале у меня была следующая строка в вспомогательном методе:
result = Users.find(:all, :order => "name collate NOCASE")
который обеспечил очень хороший поиск без учета регистра. Я не могу воспроизвести это для postgresql. Должно быть легко - любые идеи?
Спасибо.
result = Users.find(:all, :order => "LOWER(name)")
Немного от Брэда и Фрэнка.
Ответ LanecH адаптирован для Rails 3+ (включая Rails 4 и 5):
users = User.order('LOWER(name)')
Или создайте именованную область, которую вы можете использовать повторно:
class User < ActiveRecord::Base
scope :order_by_name, -> { order('LOWER(name)') }
end
users = User.order_by_name
Теперь с Rails 5.2 вы, вероятно, получите предупреждение, если используете принятый ответ.
ПРЕДУПРЕЖДЕНИЕ ОБ УСТРАНЕНИИ: Опасный метод запроса (метод, аргументы которого используются в качестве необработанного SQL), вызываемый с неатрибутивным аргументом (ами): "LOWER (?) ASC".
Альтернативой может стать использование Arel (теперь он объединен с Rails):
results = User.order(User.arel_table['name'].lower.asc)
# results.to_sql == "SELECT \"users\".* FROM \"users\" ORDER BY LOWER(\"users\".\"name\") ASC"
Рассматривали ли вы сохранение своего столбца как citext типа? Он действительно просто усваивает вызов lower(), как я понимаю. Это было бы автоматически для вас потом. Если есть моменты, когда вам нужен поиск с учетом регистра, это может быть не самая лучшая идея.
В SQL вы можете использовать ORDER BY LOWER (имя столбца), не знаете, как это сделать в Ruby. Функциональный индекс (также на LOWER (имя столбца)) поможет ускорить процесс.