I’m new to ruby rails and am trying to design my first real rails web
app.
The app is intended to model a shareware business. It will provide a
place where users can learn about new projects, track their progress,
and provide feedback. Here’s a simplified list of the model objects that
I’ll need:
Project - has title, description, creation, modification.
Release - has title, description, creation, modification belongs to
project, has tasks
Task - has title, description, creation, modification belongs to
project, belongs to release
Forum - has title, description, creation, modification has topics
Topic - has title, description, creation, modification
The key requirement is that I want these models to share some common
behavior:
- they all have a title, description, creation date, and modification
date - i want a site wide rss feed that will include changes to Projects,
Releases, Tasks… all mixed together - i want to maintain a full text search index accross all of these
models. So the search results will include Projects, Releases, Tasks… - i want to do this the “right” way, and want to make it easy for other
people to extend the system and add their own model objects that will
also share the same common behavior.
Inheritance seems like the perfect answer. I can add a page class that
all of the above models inherit from. The page class would have these
attributes and behaviors:
Page
- has title
- has description
- knows how to turn self into rss feed item
- knows how to turn self into string for text indexing
The knows how behaviors would need to be polymorphic since a subclass
might define new attributes that would also need to show up in the full
text index.
So that’s what I want, but I’m not sure what the best way to model this
in rails is. I don’t think single-table inheritance will work in this
cases because the number of subclasses should be open ended and will
each add many of their own attributes.
It might be that (I’m getting these terms from the Agile Web D.
with Rails book) strait inheritance using the “abstract_class” method is
the right solution. As I understand it that would allow each concrete
class to have it’s own table. But it would require a lot of duplication,
for example I think in my db.schema each concrete model would need to
define all the common attributes (title, description, creation,
modification) and that would be painful if I wanted to add additional
common attributes such as created_by (id of some user). I’m also not
really sure if using strait inheritance will allow me to say things like
Page.find_by_title(“some title”) and return a mixed list of matching
subclass instances.
The last option is to use polymorphic associations. So I would change my
Page model to look like this:
Page
-
has title
-
has description
-
knows how to turn self into rss feed item
-
knows how to turn self into string for text indexing