在Rails 2.x和3.x中使用ActiveRecord进行“喜欢”查询吗?

我在Rails 3.x中做这样的查询

Speaker.where("name like '%yson%'") 

但是我想避免使用特定于DB的代码。 这样做的正确方法是什么?

如果在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这样的gem,你可以在这里做以下事情:

 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') 

通常,虽然您可能必须拥有一些特定于数据库的代码,或者重构代码(即在MetaWhere中的符号上重新定义.matches运算符)以使用其他数据库。 希望您不会经常更改您的数据库,但如果您是这样,您应该有一个集中的位置,您可以在其中定义这些运算符以便重复使用。 请记住,在一个数据库中定义的运算符或函数可能在另一个数据库中不可用,在这种情况下,由于您无法执行搜索,因此具有此通用操作是没有意义的。