Matthew Shapiro wrote:
[…]
However, it turns out that the relationships aren’t working how you set
them up, even with the nested_has_many plugin. Look at the following
output from ruby’s console:
[…]
ActiveRecord::HasManyThroughAssociationPolymorphicError: Cannot have a
has_many :through association ‘Relationship#nodes’ on the polymorphic
object ‘Node#node’.
[…]
To summarize, the database has the correct records in the
node_memberships and relationships table, yet for some reason rails
can’t connect from relationships to ModelA and vice-versa. Does
anything pop out at you on why?
Looking at the error message, it appears that :through and :polymorphic
are mutually incompatible. If that’s so, and if there’s no plugin or
other technique that fixes that incompatibility, then it’s easy enough
to fix by introducing another level of association. Note, though, that
you will need nested_has_many_through if you didn’t before…
…because what we’re going to do is remove the polymorphism from Node.
The new associations (still untested, though) will look like this:
class NodeMembership < AR::B # join model since Rails won’t do
polymorphic habtm
belongs_to :node
belongs_to :relationship
end
class Relationship < AR::B
has_many :node_memberships
has_many :nodes, :through => :node_memberships
end
class Node < AR::B # make this concrete since polymorphic :through
doesn’t appear to work
belongs_to :content, :polymorphic => true
has_many :node_memberships
has_many :relationships, :through => :node_memberships
end
class Model[A,B,C…] < AR::B
you will probably want to refactor this into an abstract base class
has_many :nodes, as => :content
has_many :node_memberships, :through => :nodes
has_many :relationships, :through => :node_memberships
end
See what we’ve done here? Since has_many :through needs to be to a
concrete (non-polymorphic) association, we’ve introduced Node as a
concrete type through which to proxy the association between
NodeMembership and Model*.
Let me know if this works.
Best,
Marnen Laibow-Koser
http://www.marnen.org
[email protected]