Именование Rails has_many: through: полиморфное отношение

У меня небольшая проблема с установкой полиморфных отношений Rails has_many: through:.

Я знаю, что эта тема хорошо задокументировано на SO, но я думаю, что моя проблема связана с моей моделью и именами foreign_key, а не с синтаксисом, т.е. я думаю, что это - это проблема типа «я слишком долго смотрю на код», которая требует лишь еще одного взгляда.

В любом случае у меня есть следующая настройка:

class Milestone < ActiveRecord::Base
  has_many :responsible_items, :as => :responsibility
  has_many :responsible, :through => :responsible_items
end

class ResponsibleItem < ActiveRecord::Base
  belongs_to :responsible, :class_name => "User"
  belongs_to :responsibility, :polymorphic => true
end

class User < ActiveRecord::Base
  has_many :responsible_items, :foreign_key => :responsible_id
  has_many :responsibilities, :through => :responsible_items
end

Кажется, что это работает нормально, без ошибок, со стороны Milestone. Например, в терминале я могу написать:

Milestone.first.responsible

… И получите пустую коллекцию, как я и ожидал.

Однако со стороны пользователя выполняется:

User.first.responsibilities

… Возвращает ошибку AR:

ActiveRecord::HasManyThroughAssociationPolymorphicSourceError: Cannot have a has_many :through association 'User#responsibilities' on the polymorphic object 'Responsibility#responsibility'.

Я предполагаю, что проблема как-то связана с тем фактом, что я имею в виду отношения с пользователем как: ответственный. Это правильно?

Любая помощь будет принята с благодарностью, спасибо.


person Pete    schedule 20.04.2012    source источник
comment
какие модели являются обратной стороной полиморфных отношений? это просто веха или еще какая-то модель? и когда вы выполняете User.first.responsibility, ожидаете ли вы получить объекты Milestone? принадлежит_to: ответственность,: polymorphic = ›true   -  person Abid    schedule 20.04.2012
comment
В полиморфных отношениях будут и другие модели, но Milestone - единственная, которую я построил до сих пор. Когда я делаю User.first.responsibilities, я ожидаю объектов Milestone, да.   -  person Pete    schedule 20.04.2012
comment
А, ладно, @Abid, ты заставил меня задуматься своим вопросом. Естественно, я не смогу извлечь коллекцию responsibilities с помощью отношения: polymorphic, потому что все они принадлежат разным объектам. В результате я должен быть более конкретным в модели пользователя и указать, какие обязанности я хочу, т.е. has_many :milestone_responsibilities, :through => :responsible_items, :source => :responsibility, :source_type => 'Milestone'   -  person Pete    schedule 20.04.2012


Ответы (1)


Благодаря комментарию @ Abid я задумался о логистике привлечения всего responsibilities для пользователя, что было невозможно. Мне нужно было уточнить, чего я хочу от отношений, и в результате сработало следующее:

class User < ActiveRecord::Base
  has_many :responsible_items, :foreign_key => :responsible_id
  has_many :milestone_responsibilities, :through => :responsible_items, :source => :responsibility, :source_type => 'Milestone'
end

Затем я могу расширить это, добавив дополнительные полиморфные отношения к другим моделям, например:

class User < ActiveRecord::Base
  has_many :responsible_items, :foreign_key => :responsible_id
  has_many :milestone_responsibilities, :through => :responsible_items, :source => :responsibility, :source_type => 'Milestone'
  has_many :task_responsibilities, :through => :responsible_items, :source => :responsibility, :source_type => 'Task'
end
person Pete    schedule 20.04.2012
comment
именно это и было моей целью задать вопрос, чтобы вы могли понять, что вы делаете, чего-то не хватает :) - person Abid; 20.04.2012
comment
Спасибо! Это мне помогло! :) - person ZedTuX; 10.11.2013
comment
Вау, это именно то, что я искал! source_type спас мне день. - person Ben Lee; 27.01.2014
comment
Идеально, source_type мне тоже - person Stacked-for-life; 13.04.2016