(e-mail conversation with a colleague)
class User < ActiveRecord::Base; end
class Artist < User; end
class Investor < User; end
I don’t understand why this would be a very bad idea ?
All the users are stored in a same table as they have a lot of attributes and not much differ…
This starts with a naming of a user. As i wrote you recently, “User” name completely hides “role” from you, so it seems natural to put all the roles into User model. However, huge models tend to become harder and harder to modify and understand.
If you think of it that way:
- Person - holds authentication info
- Artist - holds info about music and albums
- Investor - holds info about artists and finance
the following becomes easy to play with:
- Person has many Artists (say, i can create several accounts for a number of my bands)
- Artist info can be edited by a group of People (my band members would like to update the news page/wiki/whatever)
- I (as a person) can represent several investors, or none at all.
- Investor can manage a number of artists, and/or a single artist can have several investors.
The reason to separate models by tasks is the very same as to separate objects from the top global Object class into more specific ones.
Speaking scientifically, it is just about “normalization” of a relational database.
If you have duplicating attributes, you have three equally good options (depending on your situation):
1. Mix them in using a module (e.g. “EntityWithTitleAndDescription”) if the duplication is just a coincidence, not a big deal (just to put some duplication into a single file to keep things cleaner).
2. Implement a separate model and associate it with appropriate models (e.g. “Account” could mediate between Person and Project to manage wikis/pages/documents/artists/etc. to avoid hardcore polymorphism between Person and Project). This is the case in a Basecamp-like app, where people have individual data as well as data, shared by a group (project).
3. Leave duplication as is: Coincidence pattern
Sometimes you have to have STI, but i believe this is not the case. E.g. i have PublicFolder and Inbox subclasses of a class Folder because they are a little special per se, not by their association to other folders.