
Class Table Inheritance
Reported by Josh H | November 10th, 2007 @ 02:37 PM
As a cleaner alternative to Single Table Inheritance, we talked about implementing Class Table Inheritance in DM.
As an added benefit, this would make it very easy to do Model Translation à la Globalize. To really facilitate switching languages, we discussed adding a context block that would allow DM to automatically choose a sub-class of a given parent class based on the supplied context (e.g. locale).
database(:default, 'en-US') do
products = Product.all
products.first.name # => Meatballs
end
database(:default, 'es-ES') do
products = Product.all
products.first.name # => Albóndigas
end
Comments and changes to this ticket
-
Matthew W November 16th, 2007 @ 11:50 AM
I suggest that if/when class table inheritance is implemented, it's done in such a way that Modules which are used as Mixins in the class hierarchy may have their own table too.
I haven't yet looked in detail at the DataMapper implementation, but this is how I'm currently doing it with an ActiveRecord plugin:
A class method 'mixin_extra_columns_from_table' defined on DataMapper::Base, usable like so:
module Publishable
def self.included(klass)
klass.send(:mixin_extra_columns_from_table, :table_name => 'publishables')
end
def publish
unless first_published_date
self.first_published_date = Date.today
end
end
... etc ...
end
class Content < DataMapper::Base
include Publishable
end
this can then be used for the actual inheritance too, if you define DataMapper::Base#inherited to call it in the right on the subclass.
-
Sam Smoot November 16th, 2007 @ 12:34 PM
- State changed from new to open
Matthew,
I'm not sure I understand the intent behind this really. Mostly your last sentence there, but your ::included hook would work fine in DM to override table names. So the mechanics of what you're saying are pretty straight-forward at least.
-
Matthew W November 16th, 2007 @ 12:43 PM
Yep sorry that last bit wasn't clear.
I was just saying, if the (class) table inheritance mechanism is designed to work for Module inclusion, then it'll be easy to extend it to work for Class inheritance too.
Pretty straightforward as you say, at least hopefully.
In my example, the Publishable module mixes in some extra columns to classes in which it's included, which are loaded from a separate publishables SQL table. This has a polymorphic foreign key to the main table for the implementing class.
so eg
create table publishables (
publishable_type enum('Content', 'Image', ...) not null,
publishable_id int not null,
author_id int not null,
first_published_at datetime
);
(If you're only using the mixin within a single class hierarchy, ie all the classes it's mixed into have a common superclass - then the foreign key needn't be polymorphic - in this case the publishable_type could be dropped).
Happy to pitch in if necessary on this feature, as it would be my main reason for moving from ActiveRecord. Just looking into the DataMapper source in more detail now :)
-
Timothy Bennett (lanaer) December 7th, 2007 @ 06:56 PM
Incidentally, what about the half-baked STI implementation currently in the code base? Are we switching to pure CTI, or defaulting to one and allowing the user to use the other via an option…?
-
Sam Smoot December 10th, 2007 @ 01:25 PM
Timothy: Ouch. :-(
Yeah, it was a bug. Should be fine now.
BTW, Class-Table-Inheritance is when you have extra tables for each sub-class that contain only the extended attributes for those types.
Just wanted to clear that up since it seemed like there was some confusion between Class-Table-Inheritance and Concrete-Table-Inheritance (where you also have multiple tables, but the sub-tables each have a full set of attributes defined). When I say "CTI", I'm referring to Class, not Concrete.
Anyways, STI should be fine now. I wouldn't say there's a need to "switch" to CTI, but that it should become an option. Not sure if it makes sense for one or the other to be a default...
-
Sam Smoot December 27th, 2007 @ 10:45 AM
- Milestone cleared.
Putting this further out for now. Would like to focus on actual bugs stomping for 0.3.0 first.
-
Dan Kubb (dkubb) April 15th, 2008 @ 03:36 AM
- Milestone cleared.
-
Sam Smoot April 27th, 2008 @ 10:19 PM
- State changed from open to invalid
Closing this for now. Needs some real solid design work to really get started. Work that should probably happen on the Wiki instead I think if anyone is interested in pasting the history from here to there...
-
Alex Coles May 8th, 2008 @ 06:50 AM
Can this ticket be kept open but set to the 1.x milestone instead? This would provide a tracking ticket for work in the wiki.
-
wildchild February 4th, 2010 @ 07:54 AM
- Tag set to mixin, spec, suggestion
Oh yes, that could be a killer feature.
-
Dan Kubb (dkubb) February 4th, 2010 @ 01:35 PM
- State changed from invalid to suggestion
I'm going to mark this as a suggestion. It's probably not something we can do until after DM 1.0 is released though, since it would require alot of internal refactoring.
I probably wouldn't want to tackle this until the query/adapter API is rewritten to use veritas (http://github.com/dkubb/veritas/) since it will probably make STI and CTI much simpler to implement.
Please Sign in or create a free account to add a new ticket.
With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »