Question

I have the following model:

class Advisor < ActiveRecord::Base
  belongs_to :course
end

class Course < ActiveRecord::Base
  has_many :advisors
  has_many :sessions
  has_many :materials, :through=>:sessions
end

class Session < ActiveRecord::Base
  belongs_to :course
  has_many :materials
end

class Material < ActiveRecord::Base
  belongs_to :session
end

I.e., every advisor teaches one course, every course has sessions, and every session has materials. I want to traverse from an advisor to all the associated materials, i.e. something like: Advisor.first.materials I tried to do:

class Advisor < ActiveRecord::Base
  belongs_to :course
  has_many :sessions, :through=>:course
  has_many :materials, :through=>:sessions
end

But it didn't work as it treated sessions as a many-to-many table: Unknown column 'sessions.advisor_id' in 'where clause': SELECT 'material'.* FROM 'materials' INNER JOIN 'sessions' ON 'materials'.session_id = 'sessions'.id WHERE (('sessions'.advisor_id = 1))

I then tried to do:

class Advisor < ActiveRecord::Base
  belongs_to :course
  has_many :materials, :through=>:course
end

In an attempt to have the association use the "materials" association in the "Course" model, but received:

ActiveRecord::HasManyThroughSourceAssociationMacroError: Invalid source reflection on macro :has_many :through for has_many :materials, :through=>:sessions.  Use :source to specify the source reflection.

Tried to use "sessions" as the source which was a nice try but made me receive only the sessions rather than the materials.

Any ideas if this is at all possible? I'm using Rails 2.3.8 (perhaps time to upgrade?)

Thanks! Amit

Was it helpful?

Solution

I want to traverse from an advisor to all the associated materials

Unless I'm missing something, using the associations specified in your first example, you can simply call materials on the associated course:

a = Advisor.first
materials = a.course.materials

OTHER TIPS

Using a has_many,through association for another has_many,:through relation will not work in rails

instead of creating a association you can just create a method to access all the materials by a Advisor

  def materials
    sessions.collect(&:materials).flatten
  end

This will work, but you wont be able to chain find queries to this method. If you want to be able to chain find methods something like @advisor.materials.find.. Then inside this method use Material.find() with appropriate conditions

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top