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

发布于 2024-10-07 12:36:34 字数 462 浏览 5 评论 0原文

我想做类似的事情:

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

我在 Arel 中的尝试:

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

但是,这变成了:

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

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

如何在 Arel 中进行 LIKE 查询?

PS Bonus——我实际上正在尝试扫描表上的两个字段,即名称和描述,以查看是否有与查询匹配的字段。那会如何运作呢?

I want to do something like:

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

My attempt in Arel:

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

However, this becomes:

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

Arel wraps the query string 'Smith' correctly, but because this is a LIKE statement it doesnt work.

How does one do a LIKE query in Arel?

P.S. Bonus--I am actually trying to scan two fields on the table, both name and description, to see if there are any matches to the query. How would that work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

暮光沉寂 2024-10-14 12:36:34

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

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

PS:

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

This is how you perform a like query in arel:

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

PS:

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)))
所有深爱都是秘密 2024-10-14 12:36:34

尝试

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

PS。

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

Aaand 已经很久了,但是 @cgg5207 添加了修改(如果您要搜索长名称或多个长名称参数或者您懒得输入,则非常有用)

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

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

Try

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

PS.

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

Aaand it's been a long time but @cgg5207 added a modification (mostly useful if you're going to search long-named or multiple long-named parameters or you're too lazy to type)

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
陌若浮生 2024-10-14 12:36:34

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

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

Reuben Mallaby's answer can be shortened further to use parameter bindings:

User.where("name like :kw or description like :kw", :kw=>"%#{params[:query]}%").to_sql
吹梦到西洲 2024-10-14 12:36:34

不要忘记转义用户输入。
您可以使用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

Don't forget escape user input.
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)

You can simplify in models/user.rb

def self.name_like(word)
  where(arel_table[:name].matches("%#{sanitize_sql_like(word)}%"))
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文