2011-11-29 23 views
4

尝试在使用url参数的rails 3中执行基本过滤器。我希望有一个可以过滤的参数白名单,并返回所有匹配的项目。我已经设置了一些范围(以带来更多的惊喜):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] 

回答

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 
+0

完美 - 我错过了'Job.scoped' – brittohalloran

1

一般来说,我更喜欢手工制作的解决方案,但对于这类问题,代码库可能会非常快速地变成一团糟。所以我会去找像meta_search这样的宝石。

+0

看起来很有趣,但得是不需要粘性的简单方法在宝石 – brittohalloran

1

一种方法是把你的条件语句插入范围:

Job.budget_min(params[:budget_min]).budget_max(params[:budget_max]) ... 

稍有不同:

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

这将仍然成为相当麻烦,因为你结了方法将在您的模型中使用类似以下内容(基于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)