In my app we have lists of people that we allow users to filter a variety of ways. For example, a user might choose 3 filters: Enrolled, Living and Lives in Wyoming.
To handle this, I've been using named scopes. The Person model has lines like this:
named_scope :enrolled, :conditions => "blah" named_scope :living, :conditions => "blah" named_scope :lives_in_state, lambda { |s| {:conditions => ["state = ?", s]}}
And then when getting the People to display in the view, I'll have:
@people = People.enrolled.living.lives_in_state("WY").paginate
So far this has worked well because I'm filtering based on pretty straightforward data requirements.
But now I'm implementing a new filter that relies not on the Person data, but on a Person instance method.
class Person
def evaluation_score ..logic to determine score end end
Say I want to filter people that have an evaluation score of 80 or higher. How can I integrate this with the named route solution that I've already implemented. What I'd like is to be able to do something like this:
@people = People.enrolled.living.lives_in_state("WY").evaluation_score_over(80).paginate
Right now I've just added a new class method
class Person
def Person.evaluation_score_over(minimum_score) self.all.reject {|l| l.evaluation_score < minimum_score} end
def evaluation_score .. logic to determine score end end
And this works. But it also breaks the chaining I can do with named scopes. So if I try this:
People.evaluation_score_over(80).enrolled.living.lives_in_state("WY").paginate
it fails. evaluation_score_over returns an array and the array doesn't have a method "enrolled".
Is there a way I can implement the kind of filtering I need to do and still get all the chaining benefits of named scopes?