【问题标题】:How to filter results by multiple fields?如何按多个字段过滤结果?
【发布时间】:2010-05-12 02:10:55
【问题描述】:
我正在使用 ruby on rails 开发一个调查应用程序,在结果页面上,我想让用户通过我在调查开始时提出的一堆人口统计问题来过滤答案。
例如,我问用户他们的性别和职业是什么。所以我在考虑为性别和职业设置下拉菜单。两个下拉菜单都默认为全部,但如果用户选择了女性和营销人员,那么我的结果页面将只有女性营销人员的回答。
我认为这样做的正确方法是使用 named_scopes,其中我的每个人口统计问题都有一个 named_scope,在此示例中为性别和职业,这将从下拉列表中获取经过净化的值以在条件条件下使用但我不确定如何动态创建 named_scope 链,因为我有 5 个人口统计问题,大概其中一些将被设置为全部。
【问题讨论】:
标签:
ruby-on-rails
filter
filtering
named-scope
【解决方案1】:
您可以将命名范围链接在一起:
def index
@results = Results.scoped
@results = @results.gender(params[:gender]) unless params[:gender].blank?
@results = @results.career(params[:career]) unless params[:career].blank?
end
不过我更喜欢使用has_scope gem:
has_scope :gender
has_scope :career
def index
@results = apply_scopes(Results).all
end
如果您将has_scope 与inherited_resources 一起使用,您甚至不需要定义索引操作。
【解决方案2】:
named_scope :gender,lambda { |*args|
unless args.first.blank?
{ :conditions => [ "gender = ?", args.first] }
end
}
如果您以这种方式编写命名范围,则可以将它们全部链接起来,并且如果您的参数之一为空白也不会中断。
Result.gender("Male") will return male results.
Result.gender("") will return male and female too.
您可以像这样链接所有方法。最后作为过滤,你可以有这样的:
Result.age(16).gender("male").career("beginer")
Result.age(nil).gender("").career("advanced") - will return results with advanced career, etc.
【解决方案3】:
试试这样的:
VistaFact.where( if active then {:field => :vista2} else {} end)
或者像这样:
VistaFact.where(!data.blank? ? {:field=>data.strip} : {}).where(some? ? {:field2 => :data2} : {}).where ...
这对我来说非常好!