2015-12-01 4 views
4

Мой синтаксис выключен. Я хочу создать область by_name, которая найдет все agencies, чей атрибут имени содержит переданную в строке (без учета регистра).Rails MySQL запрос ILIKE

Вот что у меня есть:

class Agency < ActiveRecord::Base 
    scope :by_name, ->(agency_name) { where('name ILIKE ?', "%#{agency_name}%") } 
end 

В консоли рельсах я печатаю в agencies = Agency.by_name("foo"). Вот запрос генерируется:

SELECT `agencies`.* FROM `agencies` WHERE (name ILIKE '%foo%') 

Вот сообщение об ошибке:

Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ILIKE '%foo%')

ответ

10

Я думаю, что это должно быть:

scope :by_name, lambda { |agency_name| 
    where('name LIKE ?', "%#{agency_name}%") # not ILIKE 
} 

It is in PostgreSQL ключевое слово ILIKE можно использовать вместо LIKE для сделать совпадение без учета регистра в соответствии с активной локалью. Это не в стандарте SQL, а является расширением PostgreSQL.

В MySQL у вас нет ILIKE. Оформить заказ MySQL docs on string comparison functions.


Бонус - вы также можете использовать Arel. Посмотрите:

scope :by_name, lambda { |agency_name| 
    where(Agency.arel_table[:name].matches("%#{agency_name}%")) 
} 
2

Почему да, потому что there's no such thing as ILIKE in MySQL. Только LIKE. Возможно, вы видели ILIKE как версию без учета регистра LIKE в PostgreSQL, но ваша текущая РСУБД отличается.

Лучше использует LOWER с обеих сторон для достижения в основном эквивалентный эффект:

.where('LOWER(name) LIKE LOWER(?)', "%#{agency_name}%") 

Кредит на @mu is too short его answer.

Смежные вопросы