views:

123

answers:

2

I am working on a survey application in ruby on rails and on the results page I want to let users filter the answers by a bunch of demographic questions I asked at the start of the survey.

For example I asked users what their gender and career was. So I was thinking of having dropdowns for gender and career. Both dropdowns would default to all but if a user selected female and marketer then my results page would so only answers from female marketers.

I think the right way of doing this is to use named_scopes where I have a named_scope for every one of my demographic questions, in this example gender and career, which would take in a sanitized value from the dropdown to use at the conditional but i'm unsure on how to dynamically create the named_scope chain since I have like 5 demographic questions and presumably some of them are going to be set to all.

+1  A: 

You can chain named scopes together:

def index
  @results = Results.scoped
  @results = @results.gender(params[:gender]) unless params[:gender].blank?
  @results = @results.gender(params[:career]) unless params[:career].blank?
end

I prefer however to use the has_scope gem:

has_scope :gender
has_scope :career

def index
  @results = apply_scopes(Results).all
end

If you use has_scope with inherited_resources, you don't even need to define the index action.

Jason Weathered
+1  A: 
 named_scope :gender,lambda { |*args|
    unless args.first.blank?
      { :conditions => [ "gender = ?", args.first] }   
    end
  }

If you write named scopes in this way, you can have all them chained, and if one of your params will be blank wont breaks.

Result.gender("Male") will return male results.
Result.gender("") will return male and female too.

And you can chain all of your methods like this. Finally as a filtering you can have like:

Result.age(16).gender("male").career("beginer")
Result.age(nil).gender("").career("advanced") - will return results with advanced career, etc.
dombesz