views:

900

answers:

2

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!

A: 

has many :through and polymorphic don't work together. If you try to access them directly, it should throw an error. If i am not mistaken, you have to hand write widget.people and the push routine.

I don't think it is a bug, it is just something which hasn't been implemented yet. I would imagine we see it in the feature, because everyone has a case in which they could use it.

cgr
They do work together. For example: has_many :subscriptions, :as => :subscribable has_many :subscribers, :through => :subscriptions, :source => :user
ScottJ
I will throw up an example of my failing code as a separate post in the near future :) It would save me alot of headache to figure out how to bypass that error.
cgr
+6  A: 

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
EmFi
Oh my god that is so painfully obvious I cannot believe I glazed right over it. Thanks EmFi!
No problem, I think I agonized for about a day over how to do this the first time I encountered it. Didn't help that it was one of the first things I tried to do in Rails that didn't involve following a tutorial/book.
EmFi