This is a specific case of a more general problem - how to manage
inheritance in these kinds of models. There are several things to
think about here. However they break down fairly easily. I'll use your
specific example, but some of the observations might not make a whole
lot of sense. So I will pose some questions and then give some guiding
thinking. This will not be RAILS specific thinking, but bringing
experience from enterprise class systems where we have things like
this all the time. You can generalize the thinking questioning when
the structures are even deeper.
Which attributes are common between Clients/Contractors?
- If there are a lot of attributes in common you might get away with a
single table, and a type field in the table.
Are there relationships identified that both Clients and Contractors
- If for example you had a security tag table and it needed to have
the associated "person", and it doesn't matter if the person is a
client or a contractor, then it might be worth managing that
relationship via a separate table (a Person table).
Do you expect to add new kinds of things?
- Are Clients and Contractors the only types of Persons? Will you need
to add something else in the future - e.g. Overseas Contractor which
is like a Contractor but has a bunch more fields, its own processes,
screens, etc. If so you may want to break into multiple tables.
Do you expect to have a role concept that cuts across Clients/
- Similar to relationships above, but let's imagine you also have
roles like administrator, user, ... If those roles are independent of
the Client/Contractor status, then again you might want separate
Do you have to worry about history/transition?
- If a Client can become a Contractor (or vice versa) - and you need
to manage the history (for example if all the timesheets haven't been
cleared yet), then you will have to have something a bit more complex.
Now you have to manage the temporal element when the Person can be
both. There are lots of ways of doing that, none of them ideal!
If you do decide to break into multiple tables, then make sure you
manage the relationship handling among the tables inside the Model. Do
not be tempted to put this into the Controller(s). Then you can treat
the join of the Person with the Client or the Person with the
Contractor as if they were individual Active Records. There will be
performance penalties, but performance while important is not the only
Hope this helps