Rails模型查询与许多可选参数

时间:2015-11-05 21:36:27

标签: ruby-on-rails activerecord

用户想要按属性搜索和/或订购结果。以下是一些示例请求

/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

1 个答案:

答案 0 :(得分:1)

请记住,whereorder之类的查询方法应该被链接。你想要做的是从一个基本查询开始(如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注入攻击的更多信息。