Rails 3使用范围进行多参数过滤

时间:2011-11-29 16:33:48

标签: ruby-on-rails ruby-on-rails-3

尝试使用url参数在rails 3中执行基本过滤器。我想要一个可以过滤的白色列表,并返回匹配的所有项目。我已经设置了一些范围(还有更多范围):

# in the model:
scope :budget_min, lambda {|min| where("budget > ?", min)}
scope :budget_max, lambda {|max| where("budget < ?", max)}

...但根据现有params[],使用部分,无或全部这些范围的最佳方法是什么?我已经走到了这一步,但它没有延伸到多个选项。寻找一种“链条如果存在”类型的操作。

@jobs = Job.all
@jobs = Job.budget_min(params[:budget_min]) if params[:budget_min]

3 个答案:

答案 0 :(得分:6)

我认为你很亲密。这样的事情不会扩展到多个选项吗?

query = Job.scoped
query = query.budget_min(params[:budget_min]) if params[:budget_min]
query = query.budget_max(params[:budget_max]) if params[:budget_max]
@jobs = query.all

答案 1 :(得分:1)

一般来说,我更喜欢手工制作的解决方案,但是,对于这类问题,代码库可能会很快变得混乱。所以我会选择像meta_search这样的宝石。

答案 2 :(得分:1)

一种方法是将条件放入范围:

scope :budget_max, lambda { |max| where("budget < ?", max) unless max.nil? }

由于你最终得到了:

,这仍然会变得相当麻烦
Job.budget_min(params[:budget_min]).budget_max(params[:budget_max]) ...

稍微不同的方法是在模型中使用类似下面的内容(基于here的代码:

class << self
  def search(q)
    whitelisted_params = {
      :budget_max => "budget > ?",
      :budget_min => "budget < ?"
    }

    whitelisted_params.keys.inject(scoped) do |combined_scope, param|
      if q[param].nil?
        combined_scope
      else
        combined_scope.where(whitelisted_params[param], q[param])
      end
    end
  end
end

然后您可以按如下方式使用该方法,如果它们存在于params中,它应该使用白名单过滤器:

MyModel.search(params)