我正在尝试为我的应用编写搜索查询,根据查询字符串,它将搜索与字符串匹配的组或用户。
这是我写的:
def search_api
@groups = Group.where("name ILIKE '#{params[:query]}'")
@users = User.where("first_name ILIKE '#{params[:query]}' OR last_name ILIKE '#{params[:query]}")
end
有没有办法将这两个查询合并为一个activerecord关系数组?除了蛮力迭代两个数组并将它们放入一个?
答案 0 :(得分:2)
我不确定解决方案,但我有一个安全建议。
您的查询不是SQL注入安全的。您可以传递数组而不是在SQL字符串中注入params。
以下查询是SQL注入安全的:
@groups = Group.where("name ILIKE ?", "#{params[:query]}")
@users = User.where("first_name ILIKE ? OR last_name ILIKE ?", "#{params[:query]}")
答案 1 :(得分:1)
所以这是一个解决方案。不确定它是否比保留所有内容更好,但正式它是问题的答案(除了结果不是ActiveRecord关系):
Group.connection.execute("(SELECT id, 'groups' as table FROM groups WHERE...) UNION (SELECT id, 'users' as table FROM users WHERE...)")
这将返回类型为PG::Result
的对象,您可以将其视为哈希数组。并且,正如已经说过的那样,将参数作为数组传递而不是将它们直接插入SQL中是件好事。不幸的是,如果您希望将结果作为ActiveRecord获取,则可以仅将UNION
用于对一个表的不同查询。在这种情况下,它看起来像:
Group.find_by_sql("(SELECT * FROM groups WHERE...) UNION (SELECT * FROM groups WHERE...)")