I have some questions on how to handle some inheritance I will need to do
in a Rails app.  I am implementing a process where users will be filling
out multi-step forms - a.k.a. wizards - and need to handle several
different types of wizard processes, with new ones cropping up each year
and the old ones staying archived (in other words, there will be lots of
wizard 'types' or flavors in existence).

>From a pure OO perspective, these wizards all share some common
functionality, particularly a 'state' attribute which all wizards have to
determine the current step that the user is on, and if they are finished or
not.  This state is managed internally within each different wizard type,
controlled by a state machine which could work very differently between
wizard types, however they all share the same 'completed' state at the end
as a bare minimum.

The basic class diagram I have in my head is of a base Wizard class at the
top, with the basic shared 'state' attribute and some common methods there
and the different types of wizards simply subclassing off of it.  The first
recommendation I saw for accomplishing inheritance in the ORM layer is
using single table
inheritance<http://martinfowler.com/eaaCatalog/singleTableInheritance.html>,
however it quickly became clear to me that due to the differing
columns/data that the subclasses will be storing now and into the future,
it would be a very bad choice to try and wedge these all into a single
"frankenstein" table.

Next, I saw the alternative of concrete table
inheritance<http://martinfowler.com/eaaCatalog/concreteTableInheritance.html>,
which demonstrates only making the *subclasses* be tables (i.e. each
subclass replicates the superclass data/behavior and can stand entirely on
its own).  I've started implementing this by using a combination of
subclassing (for sharing methods/behavior) and a module mixin (for sharing
the columns/data) - *gist here* <https://gist.github.com/2123152>.

This is working fine for the most part so far, however it is a bit of work
to pull up all wizard types that a user has in progress (i.e. the index
action in wizards_controller), as the differing wizard types are completely
disjoint, so to get them all in a collection I do something like this in
the index action of my WizardsController:

@wizards = Wizard.all_visible_subwizards.map(&:all).reduce(:union)

but obviously this is a lossy conversion, since the wizard type can't be
discerned from just the ID now.  So, I was thinking it would be cool if the
Wizard model could have at least a very basic table that all subclassed
wizards inherit from, even if it is just PK and type, so that a subclassed
wizard's type can be identified directly from its ID.  Following this idea,
using Wizard.get(id) could return the subclassed wizard type.  Basically,
I'm asking for the nice parts of STI, but across multiple tables. :-)
 Adding a Discriminator field triggers STI, which I don't want.  A schema
kind of like this would be ideal:

Wizard:
+----+------+--------------+
| id | type | state        |
+----+------+--------------+
| 1  | Foo  | complete     |
| 2  | Bar  | in-progress  |
| 3  | Bar  | complete     |
+----+------+--------------+

FooWizard:
+----+--------------------+
| id | other foo stuff... |
+----+--------------------+
| 1  | ...                |
+----+--------------------+

BarWizard:
+----+--------------------+
| id | other bar stuff... |
+----+--------------------+
| 2  | ...                |
| 3  | ...                |
+----+--------------------+

I've seen this referred to as multiple table
inheritance<http://en.wikibooks.org/wiki/Java_Persistence/Inheritance#Joined.2C_Multiple_Table_Inheritance>
(of
which there is an interesting
article<http://mediumexposure.com/multiple-table-inheritance-active-record/>on
mimicking it with AR using polymorphic associations), or as an
interpretation of the ambiguous class table
inheritance<http://martinfowler.com/eaaCatalog/classTableInheritance.html>
pattern,
the latter of which seems to have generated some DM-specific
discussion<http://datamapper.lighthouseapp.com/projects/20609/tickets/53-class-table-inheritance>several
years back.

Has anyone done anything like this in DM before and could offer some
suggestions?  Or should I just stick with concrete table inheritance and
put bandaids over the warts?

Thanks!
Abe

-- 
You received this message because you are subscribed to the Google Groups 
"DataMapper" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/datamapper?hl=en.

Reply via email to