views:

467

answers:

3

I have a MailingList model that has_may :people

For most of my application, I only want to get people that are active

So @mailing_list.people should only return people that are active

In my model, I can't do

def people
  self.people.find_all{ |p| !p.activated_at.nil? }
end

because that keeps calling itself. What is the ruby/rails way to automatically filter the people. Another possible issue is that I think self.people returns an array of active record objects where self.people.find_all... will return an array. This will cause some of my code to break. It's easy fixes but is there a way to return active record objects? It would be nice to have the option.

Thanks!

A: 

You can used the standard find method or a dynamic finder. Your find might read as follows:

people.find(:all, :conditions => "activated_at = nil") OR people.find_all(:conditions => "activated_at = nil")

A dynamic version of this might read as:

people.find_by_activated_at(nil)

Joe S.
+3  A: 

You can also filter at the association level.

has_many :people, :conditions => {:activated => true}
JRL
i think this is what i'm looking for under 2 conditions. the first is that i want to be able to override the filter when necessary. the second is that i need to check if "activated_at" is "not NULL" so there needs to be a way to do that. thanks!
Tony
OK i was able to accomplish the is "not NULL" requirement. the only remaining issue is how do skip the filter?
Tony
+6  A: 

This is a perfect example for a named scope:

class Person < ActiveRecord::Base
  named_scope :active, :conditions => 'activated_at is not null'
end

Then just call it:

# equivalent to Person.find(:all, :conditions => 'activated_at is not null')
@active_people = Person.active
hgimenez
You can chain named scopes too. If you have created one called :recent that only selects users created in the last week, you can call Person.active.recent to get all recently activated people.
EmFi
2 issues here. One is that I want to call this on an instance, like @mailing_list.people. The other is that I would rather not have to say ".active" since I will always be asking for active people. With that being said, there must be a way to override that restriction for when I want to look at inactive users (like on an administrator interface)
Tony
Not sure what's wrong with being explicit in calling Person.active, but your other option would be to use default_scope :conditions => 'activated_at is not null'. Then you could do Person.all and get only actives. Personally, I don't think that's a good idea though.
hgimenez
the issue is that i only want people that belong to a mailing list. Person.active would get ALL active people. i need mailing_list.people
Tony