Jason King
2006-May-20 10:49 UTC
[Rails] Polymorphic, many-to-many, self-referential data model
No matter what I try I''ve been unable to work how to get this to work with the cool ActiveRecord helpers. I''m not sure if it''s possible, Josh Susser''s blog suggests it is, but damned if I can work it out... I have: Container which can contain one or more Element. An Element is a polymorph of either a Container or a Chunk. An Element can exist in one or more Containers. I use a table called ownerships as the join between Containers and Element. Here''s some code: create_table :containers do |t| t.column :name, :string end create_table :chunks do |t| t.column :name, :string end create_table :ownerships do |t| t.column :name, :string t.column :container_id, :integer t.column :element_id, :integer t.column :element_type, :string end Then in the models: class Chunk < ActiveRecord::Base has_many :ownerships, :as => :element end class Ownership < ActiveRecord::Base belongs_to :element, :polymorphic => true # belongs_to :container end class Container < ActiveRecord::Base has_many :ownerships, :as => :element # has_many :ownerships end Ok, so far so good. The above works as expected. What is commented out is my attempt at coding the important relationship between the Container and the Ownership, not as a Element but as the parent (ie. referenced by container_id). I''ve tried a number of options, including all sort of attempts with :through and various other things. I understand why it doesn''t work, obviously the relationship defined already for Container''s access to ownerships gets in the way, or takes precedence or whatever. It doesn''t matter what I''ve tried, the result sets are always giving me the "Element" relationship of Container to Ownership, not the direct parental relationship. Any clues? -- We can evade reality, but we cannot evade the consequences of evading reality. -- Ayn Rand
Josh Susser
2006-May-20 17:28 UTC
[Rails] Re: Polymorphic, many-to-many, self-referential data model
Jason King wrote:> No matter what I try I''ve been unable to work how to get this to work with > the cool ActiveRecord helpers. I''m not sure if it''s possible, Josh Susser''s > blog suggests it is, but damned if I can work it out...Interesting combination of polymorpic and self-ref with through. I think this should do it... ----- create_table :containers do |t| t.column :name, :string end create_table :chunks do |t| t.column :name, :string end create_table :ownerships do |t| t.column :name, :string t.column :owner_id, :integer t.column :element_id, :integer t.column :element_type, :string end class Ownership < ActiveRecord::Base # to owner belongs_to :owner, :class_name => "Container", :foreign_key => "owner_id" # to elements belongs_to :element, :polymorphic => true belongs_to :container, :class_name => "Container", :foreign_key => "element_id" belongs_to :chunk, :class_name => "Chunk", :foreign_key => "element_id" end class Container < ActiveRecord::Base # to owner has_many :ownings, :class_name => "Ownership", :as => :element has_many :owners, :through => :ownings # to elements has_many :ownerships has_many :containers, :through => :ownerships, :source => :article, :conditions => "ownerships.element_type = ''Container''" has_many :chunks, :through => :ownerships, :source => :book, :conditions => "ownerships.element_type = ''Chunk''" end class Chunk < ActiveRecord::Base # to owner has_many :ownings, :class_name => "Ownership", :as => :element has_many :owners, :through => :ownings end ----- I haven''t tested this out, but I''m pretty sure it should do what you want, as it''s just a combination of the self-ref and polymorphic through patterns. The trick is that you have to disambiguate the two different associations to containers - one way is as your container, and the other is as an element. That means you need different names for those relationship. I chose "owner" to indicate an element''s container from the element''s perspective. You also have to use a different name for the two kinds of ownerships, containing and contained. Give it a shot and let me know if it works. This would be good for a writeup. -- Josh Susser http://blog.hasmanythrough.com -- Posted via http://www.ruby-forum.com/.
Jason King
2006-May-20 23:09 UTC
[Rails] Re: Polymorphic, many-to-many, self-referential data model
Josh, you wrote,>Jason King wrote: >> No matter what I try I''ve been unable to work how to get this to work with >> the cool ActiveRecord helpers. I''m not sure if it''s possible, Josh Susser''s >> blog suggests it is, but damned if I can work it out... > >Interesting combination of polymorpic and self-ref with through. I think >this should do it...Wasn''t quite right, apart from the :source => :article and :source => :book in the container, there were some other small things which brought things to a halt. Basically in the "to elements" stuff in the Container the lack of the foreign key in the "has_many :ownerships" (which I''ve renamed) meant that the JOIN was wrong. I ended up coding things like this (with some slight name changes to make more sense, and some work on the "to elements" stuff in Container). I''m still not sure if this is the best way to do it, but it seems to work, and *does* actually make sense to me :) class Container < ActiveRecord::Base # to owner has_many :ownerships, :as => :element has_many :owners, :through => :ownerships # to elements has_many :ownings, :class_name => "Ownership", :foreign_key => "owner_id" has_many :containers, :through => :ownings, :conditions => "ownerships.element_type = ''Container''" has_many :chunks, :through => :ownings, :conditions => "ownerships.element_type = ''Chunk''" end Chunk, you can probably guess from the above (just a name change from your ":ownings" to my ":ownerships" which made more sense to me. The all important (thank you, thank you, thank you) Ownership class remained the same. You truly are a legend, I knew this was complex, and throught that it might have been outside the realm of these helpers. Thanks for taking the time to code up some very helpful code. -- Every man is free to rise as far as he''s able or willing, but the degree to which he thinks determines the degree to which he''ll rise. -- Ayn Rand
Josh Susser
2006-May-20 23:26 UTC
[Rails] Re: Re: Polymorphic, many-to-many, self-referential data mod
Jason King wrote:> Wasn''t quite right, apart from the :source => :article and :source => :book > in the container, there were some other small things which brought > things to > a halt. Basically in the "to elements" stuff in the Container the lack of > the foreign key in the "has_many :ownerships" (which I''ve renamed) meant > that the JOIN was wrong.Ah yes, copy/paste is ever the bane of my postings. Cool that you got it sorted out and that it''s working for you.> I ended up coding things like this (with some slight name changes to make > more sense, and some work on the "to elements" stuff in Container). I''m > still not sure if this is the best way to do it, but it seems to work, > and *does* actually make sense to me :)If it works and makes sense to you, then it''s the right way :-) I like the way you changed the names of ownings/ownerships, I agree it reads better. And I always like to look at the SQL in the log to make sure things are getting put together right, but it sounds like you do that too so I expect you''re OK.> You truly are a legend, I knew this was complex, and throught that it > might have been outside the realm of these helpers. Thanks for taking the > time to code up some very helpful code.Glad to be of service. I love how helpful everyone is in this community, just trying to do my part. -- Josh Susser http://blog.hasmanythrough.com -- Posted via http://www.ruby-forum.com/.
Mariano Belinky
2007-Mar-19 18:40 UTC
Re: Re: Polymorphic, many-to-many, self-referential data mod
Hi, I am new to RoR, and found this example incredibly helpful. It took me a while to adapt it to my needs, but once I did it worked perfectly. Now, how would I go about creating the controller for it, ie add/delete/update elements (either containers or chunks) to a given container? I tried a scaffold on Container but that didn''t work. Can this be done "automagically", or do I need to code it by hand? many thanks, mariano -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Evan Weaver
2007-Mar-19 20:38 UTC
Re: Re: Polymorphic, many-to-many, self-referential data mod
has_many_polymorphs does all this automatically. http://blog.evanweaver.com/pages/has_many_polymorphs Evan Weaver -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Mariano Belinky
2007-Mar-20 13:08 UTC
Re: Re: Polymorphic, many-to-many, self-referential data mod
Evan Weaver wrote:> has_many_polymorphs does all this automatically. > > http://blog.evanweaver.com/pages/has_many_polymorphs > > Evan WeaverHi Evan, thanks for your reply. I''m sorry for being thick, but which part is automatic? the self-referential polymorphism or the scaffolding / controller. I looked at the link you posted, and it seems it does indeed to the polymorphism, but I''m not sure about the controller part. thanks again, Mariano -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Evan Weaver
2007-Mar-25 05:39 UTC
Re: Re: Polymorphic, many-to-many, self-referential data mod
It does not do the controller. When I posted I didn''t realize you were reanimating a year-old thread. However, I am working on adding some controller examples for tagging which might help you. Check in a few weeks. Evan Weaver -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---