如何在 Arel 和 Rails 中执行 LIKE 查询?

我想这样做:

SELECT * FROM USER WHERE NAME LIKE '%Smith%';

我在阿瑞尔的尝试:

# params[:query] = 'Smith'
User.where("name like '%?%'", params[:query]).to_sql

然而,这变成了:

SELECT * FROM USER WHERE NAME LIKE '%'Smith'%';

Arel 正确地包装了查询字符串“ Smith”,但是因为这是一个 LIKE 语句,所以它不工作。

如何在 Arel 中执行 LIKE 查询?

另外,我实际上正在扫描表中的两个字段,名称和描述,以查看是否有任何与查询匹配的字段。那要怎么做?

95837 次浏览

Try

User.where("name like ?", "%#{params[:query]}%").to_sql

附言。

q = "%#{params[:query]}%"
User.where("name like ? or description like ?", q, q).to_sql

虽然已经过去很长时间了,但是@cgg5207添加了一个修改(如果您要搜索长名称的或多个长名称的参数,或者您懒得键入,那么这个修改非常有用)

q = "%#{params[:query]}%"
User.where("name like :q or description like :q", :q => q).to_sql

or

User.where("name like :q or description like :q", :q => "%#{params[:query]}%").to_sql

下面是在 arel 中执行类似查询的方法:

users = User.arel_table
User.where(users[:name].matches("%#{user_name}%"))

附注:

users = User.arel_table
query_string = "%#{params[query]}%"
param_matches_string =  ->(param){
users[param].matches(query_string)
}
User.where(param_matches_string.(:name)\
.or(param_matches_string.(:description)))

Reuben Mallaby 的回答可以进一步缩短为使用参数绑定:

User.where("name like :kw or description like :kw", :kw=>"%#{params[:query]}%").to_sql

别忘了转义用户输入。 You can use ActiveRecord::Base.sanitize_sql_like(w)

query = "%#{ActiveRecord::Base.sanitize_sql_like(params[:query])}%"
matcher = User.arel_table[:name].matches(query)
User.where(matcher)

您可以在 models/user.rb中进行简化

def self.name_like(word)
where(arel_table[:name].matches("%#{sanitize_sql_like(word)}%"))
end