用户想要按属性搜索和/或订购结果。以下是一些示例请求
/posts?order=DESC&title=cooking
/posts?order=ASC
/posts?title=cooking
如何有条件地链接此类选项以形成查询?
到目前为止,我的方法非常难看,很快就难以维持。
def index
common = Hash.new
common["user_id"] = current_user.id
if params[:order] && params[:title]
@vacancies = Post.where(common)
.where("LOWER(title) LIKE ?", params[:title])
.order("title #{params[:order]}")
elsif params[:order] && !params[:title]
@vacancies = Post.where(common)
.order("title #{params[:order]}")
elsif params[:title] && !params[:order]
@vacancies = Post.where(common)
.where("LOWER(title) LIKE ?", params[:title])
end
end
答案 0 :(得分:1)
请记住,where
和order
之类的查询方法应该被链接。你想要做的是从一个基本查询开始(如Post.where(common)
,你在所有情况下使用),然后有条件地链接其他方法:
def index
common = Hash.new
common["user_id"] = current_user.id
@vacancies = Post.where(common)
if params[:order]
@vacancies = @vacancies.order(title: params[:order].to_sym)
end
if params[:title]
@vacancies = @vacancies.where("LOWER(title) LIKE ?", params[:title])
end
end
P.S。您的原始代码为.order("title #{params[:order]}")
。这是非常危险的,因为它可以让您进行SQL注入攻击。根据经验,从不使用字符串连接(#{...}
)与您在将结果传递给数据库时从最终用户获得的值。因此,我已将其更改为.order(title: params[:order])
。 Rails将使用此哈希构建安全查询,因此您不必担心注入攻击。
您可以在官方Ruby on Rails Security Guide中阅读有关Rails中SQL注入攻击的更多信息。