Я делаю такие запросы в Rails 3.x
Speaker.where("name like '%yson%'")
но я бы хотел избежать кода, специфичного для БД. Какой правильный способ сделать это?
Если в Rails 2.x есть способ сделать это, это тоже поможет.
Я делаю такие запросы в Rails 3.x
Speaker.where("name like '%yson%'")
но я бы хотел избежать кода, специфичного для БД. Какой правильный способ сделать это?
Если в Rails 2.x есть способ сделать это, это тоже поможет.
Вы можете использовать для этого .matches.
> t[:name].matches('%lore').to_sql
=> "\"products\".\"name\" LIKE '%lore'"
Фактическое использование в запросе будет:
Speaker.where(Speaker.arel_table[:name].matches('%lore'))
В Rails 3 или выше
Speaker.where("name LIKE ?", "%yson%")
В Rails 2
Speaker.all(:conditions => ["name LIKE ?", "%yson%"])
Избегайте прямой интерполяции строк, потому что значение не будет экранировано, и вы уязвимы для атак SQL-инъекций.
Используйте поисковую систему, такую как solr или sphinx, для создания индексов для столбцов, которые вы будете выполнять как запросы. Подобные запросы всегда приводят к полному сканированию таблицы, когда вы смотрите на план объяснения, поэтому вы действительно должны почти никогда не использовать их на производственном сайте.
Не по умолчанию в Rails, так как существует так много вариантов БД (MySQL, Postgresql, MongoDB, CouchDB...), но вы можете проверить драгоценные камни как MetaWhere, где вы можете делать такие вещи, как:
Article.where(:title.matches => 'Hello%', :created_at.gt => 3.days.ago)
=> SELECT "articles".* FROM "articles" WHERE ("articles"."title" LIKE 'Hello%')
AND ("articles"."created_at" > '2010-04-12 18:39:32.592087')
В общем, хотя вам, вероятно, придется иметь какой-то конкретный код DB или реорганизовать ваш код (например, переопределить оператор .matches для символов в MetaWhere) для работы с другой базой данных. Надеюсь, вы не будете часто менять свою базу данных, но если это так, вы должны иметь централизованное местоположение, где вы определяете эти операторы для повторного использования. Имейте в виду, что оператор или функция, определенная в одной базе данных могут быть недоступны в другом, и в этом случае, имеющий эту обобщенную операцию спорно, так как вы не сможете выполнить поиск в любом случае.