Alder Green
2006-Jul-20 14:07 UTC
[Rails] Any good alternative to single-table-inheritance?
I''m looking to implement model inheritance in a new application. Is there any good alternative to single-table-inheritance? -- -Alder
On 7/21/06, Alder Green <alder.green@gmail.com> wrote:> > I''m looking to implement model inheritance in a new application. Is > there any good alternative to single-table-inheritance? > > -- > -Alder > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/railsThere was a new plugin released recently. I havn''t had a good look at it but it certainly is an alternative http://www.agilewebdevelopment.com/plugins/inherits_from -------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060720/75eaff72/attachment-0001.html
Kevin Olbrich
2006-Jul-20 15:55 UTC
[Rails] Any good alternative to single-table-inheritance?
On Thursday, July 20, 2006, at 5:06 PM, Alder Green wrote:>I''m looking to implement model inheritance in a new application. Is >there any good alternative to single-table-inheritance? > >-- >-Alder >_______________________________________________ >Rails mailing list >Rails@lists.rubyonrails.org >http://lists.rubyonrails.org/mailman/listinfo/railsWhy do you want an alternative? _Kevin www.sciwerks.com -- Posted with http://DevLists.com. Sign up and save your mailbox.
Alder Green
2006-Jul-20 16:33 UTC
[Rails] Any good alternative to single-table-inheritance?
On 20 Jul 2006 15:57:47 -0000, Kevin Olbrich <devlists-rubyonrails@devlists.com> wrote:> > On Thursday, July 20, 2006, at 5:06 PM, Alder Green wrote: > >I''m looking to implement model inheritance in a new application. Is > >there any good alternative to single-table-inheritance? > > > >-- > >-Alder > >_______________________________________________ > >Rails mailing list > >Rails@lists.rubyonrails.org > >http://lists.rubyonrails.org/mailman/listinfo/rails > > Why do you want an alternative?I have a parent model class Foo, and two subclasses Bar and Baz. The thing is that Bar and Baz are very different. They share 4 attributes from Foo and an additional common attribute among themselves, but also each have 6-7 attributes that are non-shared. So if I implement this inheritance model with STI, I end up with a pretty large table (~20 columns), of which each model uses not more than half (and Foo instances use only a fifth). This looks very non-optimal, and is likely to get worse down the road, since Foo is expecting several additional children, each of whom would add about 6+ more non-shared attributes. I''d soon end up with a 50+ column table for producing pretty simple (10 attribute) model instances. Much unnecessary complexity. Looks like the plugin linked by Daniel would prevent that, I''d have a look at is (thanks Daniel!)> > _Kevin > www.sciwerks.com > > -- > Posted with http://DevLists.com. Sign up and save your mailbox. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- -Alder
Juan Felipe Garcia
2006-Jul-20 16:39 UTC
[Rails] Re: Any good alternative to single-table-inheritance?
Kevin Olbrich wrote:> Why do you want an alternative? > > _Kevin > www.sciwerks.comMmmm I do. I''ll explain why. As RoR learning project I decided to try reproducing the core funcionality of an internal CMS-like tool at my org. The database already followed most rails-friendly conversions, so starting was a breeze. But here''s the problem: I have in there "resources", which can be links, various documents and archives, quizzes, forums and on and on for almost 20 types of resource. There is a resources table which holds the common columns for all resources, then one table for each resource type, and some have in excess of 20 columns specific for that type of resource. If I have to mashup those into a single STI table i''ll end up with a table having between 300 and 400 columns, which I think everyone would agree it''s a bad thing. The alternative? Resource have a belongs_to polymorphic relation to all 20 different resource models, which each have a has_one dependent relationship back to the Resource model. This allows me to keep separate tables, and somehow keep everything working. The problem? My code isn''t making use of inheritance, as I can''t say: class Link < Resource and have to keep using my aggregation cludge and doing ugly stuff like: link.resource.name And I have to always remember deleting links and not resources, as the dependence for deleting goes only one way. Real support for some kind of class table inheritance would make all this moot, but I''ve been looking into ActiveRecord and can''t see it working as a simple plugin. Adding the functionality would stomp out all the simplicity from most of the current code. Doing away with the Just One Table per Model principle isn''t the ActiveRecord way. So I''m just stuck with my project, as I have to choose between an inacceptably ugly database or non-OO ugly code, and I chose Rails to flee all the uglyness that was there before. -- Posted via http://www.ruby-forum.com/.
Josh Susser
2006-Jul-20 16:57 UTC
[Rails] Re: Any good alternative to single-table-inheritance?
Juan Felipe Garcia wrote:> The alternative? Resource have a belongs_to polymorphic relation to all > 20 different resource models, which each have a has_one dependent > relationship back to the Resource model. This allows me to keep separate > tables, and somehow keep everything working. The problem? My code isn''t > making use of inheritance, as I can''t say: > class Link < Resource > > and have to keep using my aggregation cludge and doing ugly stuff like: > > link.resource.name > > And I have to always remember deleting links and not resources, as the > dependence for deleting goes only one way. > > Real support for some kind of class table inheritance would make all > this moot, but I''ve been looking into ActiveRecord and can''t see it > working as a simple plugin. Adding the functionality would stomp out all > the simplicity from most of the current code. Doing away with the Just > One Table per Model principle isn''t the ActiveRecord way. > > So I''m just stuck with my project, as I have to choose between an > inacceptably ugly database or non-OO ugly code, and I chose Rails to > flee all the uglyness that was there before.Yes, I agree with your sentiments. But Ruby has enough mojo to make the pain bearable. You can create a mixin module to share behavior in your models, and you can use delegation or a method_missing hack to make the explicit message forwarding go away. The polymorphic belongs_to assocations are still kinda ugly, but at least your code doesn''t have to be ugly. -- Josh Susser http://blog.hasmanythrough.com -- Posted via http://www.ruby-forum.com/.
Juan Felipe Garcia
2006-Jul-20 17:23 UTC
[Rails] Re: Any good alternative to single-table-inheritance?
So as it seems to be the current best alternative, I''ll post some of my model stuff as a hint: #The "parent" model for all resources, resources are listed in sections #the database table needs "instance_id" and "instance_type" columns class Resource < ActiveRecord::Base belongs_to :section belongs_to :instance, :polymorphic => :true end #A Link is one type of resource, so every link is the # "instance" of a resource class Link < ActiveRecord::Base include ResProperties has_one :resource, :as => :instance, :dependent => :destroy end #A Lesson is one type of resource, so every lesson is the # "instance" of a resource class Lesson < ActiveRecord::Base include ResProperties has_one :resource, :as => :instance, :dependent => :destroy end ... and on and on for 18 more children models #In this module I put stuff every "child" should have inherited, #for example, every resource of any type has a name, which lives in the #resources table module ResProperties def name resource.name end end Beware the possibility of orphan children. Deleting a link or lesson or whatever will take care automagically of the corresponding resource. Deleting a resource will leave the corresponding "instance" there forever. I guess some ruby magic in the ResProperties module would go a long way, as Josh suggested, I have to read deeper into my new and fresh pickaxe copy. BTW...I''m quite happy about having the has_many :though guru agreeing with my sentiments about such matters, does wonders for my newbie pride ;) -- Posted via http://www.ruby-forum.com/.
Alder Green
2006-Jul-20 17:31 UTC
[Rails] Re: Any good alternative to single-table-inheritance?
On 7/20/06, Juan Felipe Garcia <jfgcatalan@gmail.com> wrote:> So as it seems to be the current best alternative, I''ll post some of my > model stuff as a hint: > > #The "parent" model for all resources, resources are listed in sections > #the database table needs "instance_id" and "instance_type" columns > class Resource < ActiveRecord::Base > belongs_to :section > belongs_to :instance, :polymorphic => :true > end > > #A Link is one type of resource, so every link is the > # "instance" of a resource > class Link < ActiveRecord::Base > include ResProperties > has_one :resource, :as => :instance, :dependent => :destroy > end > > #A Lesson is one type of resource, so every lesson is the > # "instance" of a resource > class Lesson < ActiveRecord::Base > include ResProperties > has_one :resource, :as => :instance, :dependent => :destroy > end > > ... and on and on for 18 more children models > > > #In this module I put stuff every "child" should have inherited, > #for example, every resource of any type has a name, which lives in the > #resources table > module ResProperties > def name > resource.name > end > endThat''s the method recommended by DHH on AWDWR. Except he suggests to call the pseudo-baseclass something like ResourceMetadata. It''s in the section about Single Table Inheritance, I was just wondering whether a new "best practice" sprung up more recently, since frankly this one isn''t perfect.> Beware the possibility of orphan children. Deleting a link or lesson or > whatever will take care automagically of the corresponding resource. > Deleting a resource will leave the corresponding "instance" there > forever. > > I guess some ruby magic in the ResProperties module would go a long way, > as Josh suggested, I have to read deeper into my new and fresh pickaxe > copy. > > > BTW...I''m quite happy about having the has_many :though guru agreeing > with my sentiments about such matters, does wonders for my newbie pride > ;) > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- -Alder
Alder Green
2006-Jul-20 17:42 UTC
[Rails] Re: Any good alternative to single-table-inheritance?
On 7/20/06, Juan Felipe Garcia <jfgcatalan@gmail.com> wrote:> Kevin Olbrich wrote: > > Why do you want an alternative? > > > > _Kevin > > www.sciwerks.com > > Mmmm I do. I''ll explain why. As RoR learning project I decided to try > reproducing the core funcionality of an internal CMS-like tool at my > org. The database already followed most rails-friendly conversions, so > starting was a breeze. But here''s the problem: > I have in there "resources", which can be links, various documents and > archives, quizzes, forums and on and on for almost 20 types of resource. > There is a resources table which holds the common columns for all > resources, then one table for each resource type, and some have in > excess of 20 columns specific for that type of resource. > If I have to mashup those into a single STI table i''ll end up with a > table having between 300 and 400 columns, which I think everyone would > agree it''s a bad thing.Yup, my reason for looking for an alternative is pretty much the same.> The alternative? Resource have a belongs_to polymorphic relation to all > 20 different resource models, which each have a has_one dependent > relationship back to the Resource model. This allows me to keep separate > tables, and somehow keep everything working. The problem? My code isn''t > making use of inheritance, as I can''t say: > class Link < Resource > > and have to keep using my aggregation cludge and doing ugly stuff like: > > link.resource.nameAs Josh already hinted, you can easily (e.g. through #method_missing) have unanswered methond calls on link routed to link.resource. You can also meta-programmatically generate the boiler-plate code for the 18 children models you mentioned. I would so do that if I were you. Ultimately, as far as the code layer is concerned, Josh is right: Ruby''s meta-programming can make the pain go away. However, as I invariably end up at some point or other dealing directly with the database on all long-running project, I''d hesitate to create 50+ tables which aren''t essentially necessary for ~10 attribute models. Also, when tables might reach 400+ columns such as in your case (and in the long run definitely possible on mine), I''d start worrying about stuff like performance (e.g. select * would have to return 400 columns per record... brrr) and even (*gasp*) space. Depending on the databasse, 400 columns might really hurt when you''re doing a million inserts a day.> And I have to always remember deleting links and not resources, as the > dependence for deleting goes only one way. > > Real support for some kind of class table inheritance would make all > this moot, but I''ve been looking into ActiveRecord and can''t see it > working as a simple plugin. Adding the functionality would stomp out all > the simplicity from most of the current code. Doing away with the Just > One Table per Model principle isn''t the ActiveRecord way. > > So I''m just stuck with my project, as I have to choose between an > inacceptably ugly database or non-OO ugly code, and I chose Rails to > flee all the uglyness that was there before. > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- -Alder
Juan Felipe Garcia
2006-Jul-20 17:55 UTC
[Rails] Re: Re: Any good alternative to single-table-inheritance?
If I was 20 yrs. old punk once again I would have already wrote something like: class HyperActiveRecord < ActiveRecord::Base And go on overriding the columns, attributes, find, update, insert,... methods with the sql join mojo necessary to have proper model inheritance.. But I''m too old and lazy by now. Instead my project is stopped while I ponder about easier options. Anyone trying, feel free to pick up my class name, I like it a lot :) -- Posted via http://www.ruby-forum.com/.
Alder Green
2006-Jul-20 18:41 UTC
[Rails] Re: Re: Any good alternative to single-table-inheritance?
On 7/20/06, Juan Felipe Garcia <jfgcatalan@gmail.com> wrote:> If I was 20 yrs. old punk once again I would have already wrote > something like: > > class HyperActiveRecord < ActiveRecord::Base > > And go on overriding the columns, attributes, find, update, insert,... > methods with the sql join mojo necessary to have proper model > inheritance.. But I''m too old and lazy by now. Instead my project is > stopped while I ponder about easier options.Don''t brood over this too much; either go with the AWDWR best practice (the minor problems you saw in it are solveable, and you end up with something that''s not really kludgy in any way) or have a look at the plugin. Either way, in several months you''ll be such a Rails whiz you''d be able to switch MOs in less time than you''ll take "pondering your options" right now ;-)> Anyone trying, feel free to pick up my class name, I like it a lot :) > > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- -Alder
The are a few solutions if you do a google ''rails single table inheritance'' but none are 100%, for example some functionality is lost such as associated join along the chain of inheritance or they are db specific such as Postgres table inheritance. I started by using polymorphic joins to a common model but the code is kinda odd, it would be great if the Rails core had STI implemented... Does anyone know of any progress in this area? -- 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 -~----------~----~----~----~------~----~------~--~---