ActiveRecord, has_many :through, and Polymorphic Associations

activerecord, polymorphic-associations, ruby-on-rails

Solution

There is a known issue with Rails 3.1.1 that breaks this functionality. If you are having this problem first try upgrading, it's been fixed in 3.1.2

You're so close. The problem is you're misusing the :source option. :source should points to the polymorphic belongs_to relationship. Then all you need to do is specify :source_type for the relationship you're trying to define.

This fix to the Widget model should allow you do exactly what you're looking for.

class Widget < ActiveRecord::Base
  has_many :widget_groupings

  has_many :people, :through => :widget_groupings, :source => :grouper, :source_type => 'Person'
  has_many :aliens, :through => :widget_groupings, :source => :grouper, :source_type => 'Alien'
end

Problem

Folks, Want to make sure I understand this correctly. And please disregard the case for inheritance here (SentientBeing), trying to instead focus on polymorphic models in has_many :through relationships. That said, consider the following... ``` class Widget < ActiveRecord::Base has_many :widget_groupings has_many :people, :through => :widget_groupings, :source => :person, :conditions => "widget_groupings.grouper_type = 'Person'" has_many :aliens, :through => :widget_groupings, :source => :alien, :conditions => "video_groupings.grouper_type = 'Alien'" end class Person < ActiveRecord::Base has_many :widget_groupings, :as => grouper has_many :widgets, :through => :widget_groupings end class Alien < ActiveRecord::Base has_many :widget_groupings, :as => grouper has_many :widgets, :through => :widget_groupings end class WidgetGrouping < ActiveRecord::Base belongs_to :widget belongs_to :grouper, :polymorphic => true end ``` In a perfect world, I'd like to, given a Widget and a Person, do something like: ``` widget.people << my_person ``` However, when I do this, I've noticed the 'type' of the 'grouper' is always null in widget_groupings. However, if I to something like the following: ``` widget.widget_groupings << WidgetGrouping.new({:widget => self, :person => my_person}) ``` Then all works as I would have normally expected. I don't think I've ever seen this occur with non polymorphic associations and just wanted to know if this was something specific to this use case or if I'm potentially staring at a bug. Thanks for any help!

Original source