如何按多个字段过滤结果?

时间:2010-05-12 02:10:56

标签: ruby-on-rails filter filtering named-scope

我正在使用ruby on rails和结果页面上的调查应用程序我想让用户通过我在调查开始时提出的一系列人口统计问题来过滤答案。

例如,我问用户他们的性别和职业是什么。所以我在想性别和职业的下拉。两个下拉菜单都会默认为全部,但如果用户选择了女性和营销人员,那么我的结果页面只会给女性营销人员提供答案。

我认为这样做的正确方法是使用named_scopes,我的每个人口统计学问题都有一个named_scope,在本例中为性别和职业,这将从下拉列表中获取一个已清理的值,以便在条件下使用但我不确定如何动态创建named_scope链,因为我有5个人口统计学问题,并且可能有些问题将被设置为全部。

3 个答案:

答案 0 :(得分:7)

您可以将命名范围链接在一起:

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_scopeinherited_resources一起使用,则甚至无需定义索引操作。

答案 1 :(得分:3)

 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.

答案 2 :(得分:0)

尝试这样的事情:

VistaFact.where( if active then {:field => :vista2} else {} end)

或者像这样:

VistaFact.where(!data.blank? ? {:field=>data.strip} : {}).where(some? ? {:field2 => :data2} : {}).where ...

这对我来说非常好!