Обход модели в рельсах: от ребёнка к ребёнку родного брата - PullRequest
0 голосов
/ 31 октября 2010

У меня есть следующая модель:

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

Т.е. каждый консультант преподает один курс, у каждого курса есть занятия, и у каждого занятия есть материалы. Я хочу перейти от советника ко всем связанным материалам, то есть что-то вроде: Advisor.first.materials Я пытался сделать:

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

Но это не сработало, поскольку он рассматривал сессии как таблицу «многие ко многим»: 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))

Затем я попытался сделать:

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

В попытке создать ассоциацию используйте ассоциацию «материалы» в модели «Курс», но получили:

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

Пытался использовать «сессии» в качестве источника, что было хорошей попыткой, но заставило меня получать только сессии, а не материалы.

Есть идеи, если это вообще возможно? Я использую Rails 2.3.8 (возможно, время для обновления?)

Спасибо! Amit

Ответы [ 2 ]

0 голосов
/ 31 октября 2010

Я хочу перейти от советника ко всем связанным материалам

Если я что-то не упустил, используя связи, указанные в первом примере, вы можете просто позвонить materialsна связанный course:

a = Advisor.first
materials = a.course.materials
0 голосов
/ 31 октября 2010

Использование has_many через ассоциацию для другого has_many: сквозное отношение не будет работать в рельсах

вместо создания ассоциации вы можете просто создать метод, чтобы советник мог получить доступ ко всем материалам

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

Это будет работать, но вы не сможете связать запросы поиска с этим методом.Если вы хотите иметь возможность цепочки методов поиска, например, @advisor.materials.find.., то внутри этого метода используйте Material.find() с соответствующими условиями

...