I remember reading about
has_many_polymorphs a couple of years ago, then again last year. Each time around when I wanted some sort of polymorphic
has_many :through. Each time I figured, “Eh, it’s just another couple of tables” or “I can just map them in a method in the model, there’s not that much data”. But this time I finally gave it a try.
First I got this error when using the gem with Rails 3:
has_many_polymorphs/support_methods.rb:69:in `warn': wrong number of arguments (1 for 3) (ArgumentError). So I looked at the github network graph and found a branch that seemed to fix that.
That worked, but next I got this:
Could not find a valid class for :collections_items (tried CollectionsItem). If it's namespaced, be sure to specify it as :"module/collections_items" instead. (ActiveRecord::Associations::PolymorphicError) What are they trying to do, pluralize post positive adjectives? My model is named
CollectionItem, which seems sensible to me.
This time I try adding a
:through option to set it straight.
has_many :collection_items has_many_polymorphs :items, :through => :collection_items, :from => [:sprites, :collections]
Now I get the following amazing error message:
has_many_polymorphs/class_methods.rb:441:in `create_has_many_through_associations_for_children_to_parent': You can't have a self-referential polymorphic has_many :through without renaming the non-polymorphic foreign key in the join model. (ActiveRecord::Associations::PolymorphicError)
This probably makes sense to everyone except me, but I’ve got to work with the skills I’m given.
What I’d really like is for polymorphic
has_many :through to ‘just work’(TM).
Something kind of EXACTLY LIKE this:
class CollectionItem < ActiveRecord::Base belongs_to :collection belongs_to :item, :polymorphic => true end class Collection < ActiveRecord::Base belongs_to :user has_many :collection_items has_many :items, :through => :collection_items end
Why is that so hard? No one will ever know…
So I did what I always do:
class Collection < ActiveRecord::Base belongs_to :user has_many :collection_items def items collection_items.map(&:item) end end
After all, there’s not that much data anyway…