我正在写一个rails 3应用程序,我有一个用户数据库表。用户具有first_name和last_name列。在我列出用户的页面上,我想要一个允许用户过滤列表的文本搜索框。他们需要能够在搜索框中输入以下内容之一: - 用户的名字 - 用户的姓氏 - 用户的全名(例如“Smith,John”)
我不知道如何编写将返回这些结果的where子句。我得到的最接近的是下面,但是连接的字段部分不起作用。
where('(first_name LIKE :search) or (last_name LIKE :search) or ("#{last_name}, #{first_name}" LIKE :search)', :search => "%#{search}%")
我也有兴趣知道是否有更好的方法来处理我的OR语句,因为这个条款变得非常笨重。
感谢您的帮助!
答案 0 :(得分:2)
您必须记住,where
将转换为SQL,如果要将连接列与搜索字符串进行比较,则必须在数据库/ sql级别执行此操作。
现在这就变得棘手,因为sql中的连接因数据库而异。
在Postgresql和Oracle中,您可以编写如下内容:
where("(first_name LIKE :search) or (last_name LIKE :search) or (last_name || ',' || first_name LIKE :search)", :search => "%#{search}%"
不幸的是,Mysql不支持标准连接运算符||
,使用mysql,你必须使用concat
代替:
where("(first_name LIKE :search) or (last_name LIKE :search) or (concat(last_name, ',', first_name) LIKE :search)", :search => "%#{search}%"
答案 1 :(得分:2)
如果它对其他人有帮助,这就是我采用的解决方案:
def self.search(query)
if query.blank?
scoped
else
sql = query.split.map do |word|
%w[first_name last_name].map do |column|
sanitize_sql ["#{column} LIKE ?", "%#{word}%"]
end.join(" or ")
end.join(") and (")
where("(#{sql})")
end
end
感谢Railscasts的Ryan Bates提供此解决方案。