8

Im having a bit of an issue setting up a Rails has_many :through :polymorphic relationship.

I'm aware this subject is well documented on SO but i think my problem is down to my model and foreign_key names as opposed to syntax i.e i think this is a "i've been looking at code too long" issue that just requires another set of eyes.

Anyway i have the following setup:

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

This seems to work fine, without error, from the Milestone side of things. For example in terminal i can write:

Milestone.first.responsible

…and get an empty collection as i'd expect.

However, from the User side of things, running:

User.first.responsibilities

…is returning an AR error:

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

I'm assuming the issue is something to do with the fact that i am referring to the User relationship as :responsible. Is this right?

Any help would be much appreciated, thanks.

Community
  • 1
  • 1
Pete
  • 1,472
  • 2
  • 15
  • 32
  • 1
    what are the models that are the other side of the polymorphic relationship? is it just milestone or any other model as well? and when you are doing User.first.responsibilities are you expecting to get Milestone objects ? belongs_to :responsibility, :polymorphic => true – Abid Apr 20 '12 at 16:03
  • There will be other models in the polymorphic relationship but Milestone is the only one i've built so far. When i do `User.first.responsibilities` i'm expecting Milestone objects yes. – Pete Apr 20 '12 at 16:07
  • 1
    Ah ok @Abid you made me think with your question. I'm naturally not going to be able to pull out a collection of `responsibilities` via the :polymorphic relationship because they all belong to different objects. As a result i have to be more specific on the User model and state which responsibilities i want i.e `has_many :milestone_responsibilities, :through => :responsible_items, :source => :responsibility, :source_type => 'Milestone'` – Pete Apr 20 '12 at 16:18

1 Answers1

12

Thanks to @Abid's comment i got thinking about the logistics of pulling in all responsibilities for a user, which wasn't going to be feasible. I needed to be more specific about what i wanted from the relationship and as result defining the following worked:

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

I can then extend this as i add further polymorphic relationships on other models for example:

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
Pete
  • 1,472
  • 2
  • 15
  • 32