Topic: Delving deep with has_many :through

Hi everyone,

Looking for guidance with extended has_many :through relationships.  Here's the setup:

class Worker < ActiveRecord::Base
  has_many :assignments, :dependent => :destroy
  has_many :slots, :through => :assignments
end

class Assignment < ActiveRecord::Base
  belongs_to :worker
  belongs_to :slot
end

class Slot < ActiveRecord::Base
  has_many :assignments, :dependent => :destroy
  has_many :workers, :through => :assignments
  belongs_to :event
end

class Event < ActiveRecord::Base
  has_many :slots, :dependent => :destroy
  has_many :assignments, :through => :slots
end


At various places in the application, I need to be able to display all the workers connected to an event, or all the events connected to a worker.

I can't seem to chain has_many :through relationships together, so here's my solution.

class Event < ActiveRecord::Base
  has_many :slots, :dependent => :destroy
  has_many :assignments, :through => :slots

  def workers
    returning @workers = [] do |e|
      assignments.map(&:worker).each { |worker| @workers << worker unless @workers.include?(worker) }
    end
  end
end

class Worker < ActiveRecord::Base
  has_many :assignments, :dependent => :destroy
  has_many :slots, :through => :assignments

  def events
    returning @events = [] do |e|
      slots.map(&:event).each { |event| @events << event unless @events.include?(event) }
    end
  end
end


Using my custom workers and events methods, I get back distinct records (which is a requirement).  Am I over-engineering the problem?

Re: Delving deep with has_many :through

This will probably have better performance as it keeps it all in one query.

# in Event
def workers
  Worker.find(:all, :include => :slots, :conditions => ['slots.event_id=?', id])
end

# in Worker
def events
  Event.find(:all, :include => :assignments, :conditions => ['assignments.worker_id=?', id])
end


There might be a better way.

Railscasts - Free Ruby on Rails Screencasts