views:

69

answers:

2

I have four model classes:

class Group < ActiveRecord::Base
  has_many :projects
  has_many :personal_blogs
end

class Project < ActiveRecord::Base
  has_many :events, :as => :event_producer
end

class PersonalBlog < ActiveRecord::Base
  has_many :events, :as => :event_producer
end

class Event < ActiveRecord::Base
  belongs_to :event_producer, :polymorphic => true
end

I want to find all of the events for a particular group. I figure this is a has_many :through association, but how do I specify a has_many on Group that finds all events in the projects or personal_blogs of a group? I could, of course, specify two associations and concatenate the results, but then I have to re-sort, limit, condition, etc. in Ruby, which could potentially be a performance nightmare with many events. I'd like to do this within ActiveRecord to avoid such a nightmare.

+4  A: 

You could define a method in the Group class like next:

class Group < ActiveRecord::Base
  has_many :projects
  has_many :personal_blogs

  def events
    Event.find(:all, :conditions => ['(type = ? AND event_producer_id IN (?)) OR (type = ? AND event_producer IN (?))', 'project', project_ids, 'personal_blog', personal_blog_ids])
  end
end

If you don't like SQL like the previous one, it's always possible to use Single Table Inheritance. This solution depends on your classes attributes and behavior, but will allow you to use a "has_many through" association.

fjuan
This doesn't actually work for me, because I need to restrict the search to a particular group. The reference to the group is polymorphic across a join, making the SQL considerably more complex.
This is actually restricted by Group. Notice that I'm using "project_ids" and "personal_blog_ids" collections that are already filtering out the projects and personal_blogs that don't belongs to the actual group.
fjuan
A: 

Why not just do:

class Group < ActiveRecord::Base
  has_many :projects
  has_many :personal_blogs

  def all_events
    projects.events + personal_blogs.events
  end
end
Midwire
"I could, of course, specify two associations and concatenate the results, but then I have to re-sort, limit, condition, etc. in Ruby, which could potentially be a performance nightmare with many events. I'd like to do this within ActiveRecord to avoid such a nightmare."
my bad. it helps when I read the whole thing.
Midwire