Wednesday, June 3, 2009

To ORM or Not to ORM.


Sara Taraporella recently added this very interesting post to her blog. In this post she argues for a separation between domain models and ORM models. There is a pretty lively discussion in the comments that I found useful.

For me it is situational and so for the most part I think being somewhere between these extremes is nice. Something that keeps me from having to do lots and lots of transformations but also keeps me from having to touch too many files when something changes. Active Record is the poster child for combining ORM with the domain, and in the situation where you have complete control to define and change your DB it is great, though I think it comes at the cost of testability. In the comments Clinton Begin describes a situation where other applications need to consume the same DB and require changes. In this case or in the case of a legacy DB you might find yourself gravitating towards the opposite end of the spectrum, which is what Sara is advocating. Complete separation of these concerns.

I recently attended a talk by Drew Olson at the Chicago ruby user group about Data Mapper (among other things). Data Mapper is definitely a step away from the the purity of active record. With active record your DB schema describes your domain model and so you stay DRY. Data mapper says you need an explicit mapping. This buys you flexibility at the cost of being explicit and potentially redundant in describing the relationship between the domain and the database.

I see Active Record as one extreme and Sara's perspective as the opposite. Datamapper is a step towards the middle, and with the changes in Rails 3 the door will be open for people to use data mapper instead of active record. So it appears that Rails is mellowing in its old age, going for a less extreme worldview. Or maybe the world has moved towards rails' view of the world. In the end a little of both are a good thing, I think.

3 comments:

Kerry Buckley said...


Active Record is the poster child for combining ORM with the domain, and in the situation where you have complete control to define and change your DB it is great, though I think it comes at the cost of testability.


That's an interesting comment – could you expand a little on why you think testability suffers when using Active Record?

Unknown said...

AR has column names and such in the runtime, you can generate tables from DM. They simply approach it from different directions. I think describing either as more or less DRY is a misuse of the concept (don't repeat Domain Knowledge, ie: Constants or Behaviour).

Sara is mixing concepts. I'd disagree that a Form (which seems to basically be a Controller for her) is a part of your Domain Model. Repository, Presenter, Controller and Domain Model are all different things, and I suppose you might could make a better case for it, but I find the example lacking.

The broader idea that your Domain Model is not your Persistence Layer is a good one I think, but I know of very few O/RMs that are truly mappers for Plain Old X Objects without at least some concessions. At the end of the day, I think it's just not very practical when you have in-memory databases, mocks, stubs, etc at your disposal.

And look, I dislike Relational databases as much as the next guy, but I'll say it now: this JSON/Document/OODB stuff is a fad. You're going to have to spend some real money for real OODB (and it's great, but nothing's perfect, it has it's own issues), and let me know when someone finds a JSON/Document store that can come within 1 order of magnitude of the performance of SQLServer or Oracle on hundreds of millions of rows.

Just because the OSS Databases suck (hey, I like/use Postgres, but price being equal, I'm picking SQLServer every time) doesn't mean RDBMSs are dead, much less inferior. Quite the opposite if the Rails community were to investigate as opposed to rushing from fad to fad to fad ( new deployment stack anyone? :-p ).

So long as the Rails guys fight community against community, so long will they be a little people, a silly people, greedy, barbarous, and cruel... ;-)

Unknown said...

At some point you have to define your database columns, whether you're sitting at a terminal typing in CREATE TABLE statements, using a UI to configure the table, or specifying the properties in the DataMapper model. I don't see AR's approach more DRY than DM, or vice versa -- the knowledge has to live someplace and it takes roughly the same level of effort to define it in each of those places.

One difference with having it inside the DataMapper model is that you don't have to refer to anywhere else to know what properties your model has.

It also allows things like auto-migrate, in which you can add/remove a property, or adjust a constraint, and regenerate the table quickly from the model snapshot.

Sure once you start deploying to production, you have to write migrations just like AR. Although it is very useful when doing local development to be able to regenerate all the tables quickly in order to test something out.