Active Record Pattern Has No Consequences?

I've been looking at Rails lately, partly to see what the hype is about and partly to see what useful elements can carry over into my ColdFusion development. One of the things that I have pretty deep concerns over is its focus on the Active Record pattern. Most books and tutorials go so far as to recommend building your database first and then working backwards from that!

It would be interesting to have a discussion on whether it is a bad idea (and I think it is) to work backwards from a relational database model and hammer this down on top of your domain model. But I don't want to go there just yet. What I wanted to talk about is the Active Record design pattern itself.

Active Record (or ActiveRecord if you prefer) underpins almost everything you will see about Rails. It is the reason why "the database comes first" for most Rails folks. And I won't argue that it seems to have some nice advantages. It handles relationships and SQL and all that boring database stuff. It makes things like scaffolding not only possible, but fairly simple. Because a lot of web applications ARE actually just CRUD front ends for database data, Active Record might often be just the ticket.

However, Active Record is supposed to be a design pattern. So why it that if I Google for "'Active Record Pattern' Consequences", I get only 33 results? 33! Where a search for "Active Record Pattern" alone brings back ten thousand?

Design Patterns are supposed to be defined in a very specific way. One of the parts of that definition is to describe the consequences. These are the drawbacks or implications of using that pattern. I'm not sure why, but for some reason no one seems to be considering the consequences of the Active Record pattern. In fact, even of the 33 results I could find, none of them actually discuss the consequences of the pattern. They just happen to be results where the word "consequences" happened to be somewhere on the page. I could not find a single pattern definition for Active Record that actually discussed the consequences (or most of the other established elements that should be present when defining a pattern).

First, does someone know if I am missing something? Is there some reason why no one would be considering the consequences of this hugely popular pattern? The cynic in me almost wants to think that someone (I believe it was Fowler, who I admire greatly) came up with this idea, and then a lot of other people just grabbed it and ran with it, slavishly applying it without really giving it any more thought. Does anyone have any ideas on this? Why is Active Record, as far as I can tell, such a popular "pattern" that actually doesn't seem to have a real pattern definition?

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
"Most books and tutorials go so far as to recommend building your database first and then working backwards from that!"

I'm not sure what books you've looked at, but the ones I've read focused on the front-end first?
# Posted By Damien McKenna | 8/21/07 9:16 AM
I'm not sure what you're looking at that does not do this. Do you have a link? I'm holding the Rails bible "Agile Web Development with Rails" in my hands and the very first thing that you do in the very first example is create a database and use that to generate scaffolds.
# Posted By Brian Kotek | 8/21/07 9:22 AM
Check out the first comment on the following page:
http://terrychay.com/blog/article/simple-prescript...
# Posted By Kyle Hayes | 8/21/07 9:40 AM
What about Rails and ActiveRecord prevents you from doing it the way you like to?
# Posted By Sammy Larbi | 8/21/07 9:57 AM
People seem to be missing the point of this blog entry, which is not a debate on Rails, but an inquiry into why it is so difficult to find a proper pattern definition for the ActiveRecord pattern. It seems to be that this approach has significant consequences and implications, but no one seems to have investigated any of them.

@Sami, nothing is technically stopping me from "doing it the way I want to". I just dislike the data-centric approach that is pushed by Rails. Everything seems to revolve around the database and, as a result, the properties of the ActiveRecord objects. In other words, the focus is on data, not behavior. I'd be very interested to see an article or book that actually talks about building a real domain model within a Rails app.
# Posted By Brian Kotek | 8/21/07 10:05 AM
Brian, I forgot about that, it has been two years since I read the early part of the book. The main tutorial in the book, the shopping cart, works from the front backwards - they plan out what the interface will be and from that decide what the schema should be to support it, and this is what I was thinking of when I replied. These days I mainly read part 3, the reference material.
# Posted By Damien McKenna | 8/21/07 10:07 AM
http://tinyurl.com/26xzn5

This is the Patterns of Enterprise Applications book. Go to page 160 for Active Record.
# Posted By Kyle Hayes | 8/21/07 10:14 AM
They do sketch out some "use cases" which is nice I suppose. But there is no discussion of actual domain modeling. They jump right to blocking out database tables and fields. In any event, the front end is a totally separate topic from the model.
# Posted By Brian Kotek | 8/21/07 10:17 AM
Thanks Kyle, at least that is more than I could find anywhere else. But even that is not a very good pattern definition. Where are the sections on consequences, related patterns, participants, etc.? The fact that none of these seem to exist is bizarre to me, considering how popular this pattern has become.
# Posted By Brian Kotek | 8/21/07 10:22 AM
@Damien

>they plan out what the interface will be and from that
>decide what the schema should be to support it

...and that what really bothers me about Rails. It shouldn't be "schema to support it," it should be "domain objects to support it" as Brian pointed towards in his "there is no discussion of actual domain modeling." The schema shouldn't be approached until figuring out how to persist the domain objects. The paradigm mismatch between OO and relational storage is too big to have a schema = object model reflection do your application justice.

@kyle and brian (re: Fowler's book)

I think the rest of the definition is in the full book...he does point out some of AR's shortfalls in the available excerpt.
# Posted By Joe Rinehart | 8/21/07 11:52 AM
Joe: fair point. Maybe they're focusing on a lower-end of the market, their ubiquitous "90%" of projects that don't need a 6-month model planning cycle? I would like to see what their rationale is, though, especially given that Mr Fowler is a rubyist.
# Posted By Damien McKenna | 8/21/07 12:14 PM
PoEAA is written less formally than GoF. The consequences are described in "When to Use It." Also, interestingly, the book says "the essence of Active Record is a Domain Model."
# Posted By Patrick McElhaney | 8/21/07 1:58 PM
After reading your post, I did a little poking around on various blogs and programming publications to see if I could find a good pattern definition for Active Record. I found several overlapping and often vague definitions. I also found some discussion of the strengths and weaknesses of the pattern, but mostly I found bloggers attempting to describe an implementation of the pattern in programming language X.

In my own limited experience, most developers really don't have an interest in theoretical debates. They want to find a solution that works at least marginally well and apply it to a specific problem they are facing at that moment. A few people might document their findings to share with others, but they don't take the time to really delve into the theory behind the solution.

Still, I would expect to find more on the theory behind Active Record than I did. The cynic in me thinks that people (like Fowler) who spend the time and energy to describe programming theory want you to buy their books instead of reading about it for free.
# Posted By Rob Munn | 8/21/07 2:23 PM
@damien:

Thanks, and I agree: to me, anyone who embarks on a 6-month model planning cycle is probably doomed! I'm considered fairly formal in that I like to follow UP for discovery/decomposition, and that's rarely more than a day or so of whiteboard and Enterprise Architect UML in a given iteration.

It's not that I don't believe in shooting the relational fish in the barrel. I just think you should know what kind of a gun you're holding....you may be shooting a shark with a slingshot, and you'll just make him angry.
# Posted By Joe Rinehart | 8/21/07 3:33 PM
I stopped for lunch, started to write a long comment, and it turned into a long blog entry, complete with spiffy diagrams:

http://www.firemoss.com/blog/index.cfm?mode=entry&...
# Posted By Joe Rinehart | 8/21/07 3:34 PM
Brian,

If I had a blog I would have posted the same (or very similar, anyways) thing. It seems to me like in both Rails and PHP the approach is database first, model next. This implementation of the ActiveRecord pattern seems to produce an anemic domain model.

I took last week off work and decided to learn and compare OO implementations in PHP with that in CF. I even checked out some of MVC frameworks, CakePHP and CodeIgnitor, both of which use the ActiveRecord Pattern. I kept finding myself wondering, "how do I create 'smart' getters and setters instead of just mirroring my database table and fields?" I decided to generate some models in both frameworks and when I looked at the resulting code all I saw was framework specific code ($name = tableName; is all that was in the model).

I started a thread on the SitePoint forums to discuss available DI/IoC frameworks for PHP and everybody seemed to think that a DI container was unnecessary. I guess it figures since they put their framework specific code directly in their model - everything is coupled together anyways so why bother with DI?).

To get back to your topic though, I had the same problem when I was considering the ActiveRecord Pattern for my own applications. I had a hard time finding anything related to the disadvantages of the pattern. I finally decided not to use it because I like having a service layer as a single API for CRUD and bulk queries. I was afraid that if I used the ActiveRecord pattern I would not be able to changed the front-end out to Flex or Flash without major modifications.
# Posted By Aaron Roberson | 8/21/07 3:53 PM
@Brian,

This was always my beef with Rails. Check out Django or RiFE both of which allow you to declaratively describe your object model and then just gen the appropriate db tables once you've described your rules for persisting objects. Both are a little limited in terms of the ORM they support, but at least they start by describing the domain object and then worry about persistence afterwards.
# Posted By Peter Bell | 8/21/07 3:56 PM
This stuff always makes me crazy as a long-time ColdFusion developer who also is very much a participant in the Rails world!

Let's start with the whole ActiveRecord thing first. The downside of the ActiveRecord pattern is that it's tied to a database or view by definition. Regardless of the language, that's a problem. Maybe. Depends on your application. And it means that at some point either you'll have to code-generate the db from the object or the object from the db. It's not a language thing, it's a chicken and the egg thing. You can work forwards or backwards, but the very definition of the pattern *assumes* a database -- there's no point in abstracting that out because you are making the existence of the matching database table (or view) a part of your initial design. So you've got your data access built-in plus some domain logic.

Is ActiveRecord always the *right* way to model objects in your app -- heck no. Only ones that get persisted to the db for starters.

Now on to Rails. Nothing forces you to use ActiveRecord for *every* domain object. Nothing forces you to do iterative development using the database as your primary domain modeling tool. All the higher-end Railsistas are using tools like RSpec to specify behavior of objects and mock them out LONG before you hit a database. Take some of this with a grain of salt -- I mean do any of you build your apps like the OrangeWhip app of Ben's in the CF books by Adobe? :) :)

So ActiveRecord is a pattern that has its place, but is no more the only one than the Gateway/DTO/bean model that folks in the CF world slavishly use because they've seen a few blog posts. Use them in the right place and they rock
# Posted By John Paul Ashenfelter | 8/21/07 4:18 PM
Hadn't seen Rspec before - interesting!
# Posted By Peter Bell | 8/21/07 4:23 PM
And just because I like to grin about things, here's a quick discussion of some of the problems with the ActiveRecord pattern

"[the ActiveRecord pattern] two stunting problems: lack of associations and inheritance"

That's from, interestingly, the docs for ActiveRecord (http://api.rubyonrails.com/files/vendor/rails/acti...)

and also explains how the Rails ActiveRecord implementation solves both of those problems.
# Posted By John Paul Ashenfelter | 8/21/07 4:47 PM
One obvious other pattern is the much more common (at least in the ColdFusion world) DataMapper pattern (actually a 'subclass' of the Mapper pattern). http://www.martinfowler.com/eaaCatalog/dataMapper....

http://www.loudthinking.com/arc/000209.html has a brief discussion of the pros/cons of ActiveRecord vs DataMapper and basically applies the 80/20 rule. I agree.

As an aside, one of the key development practices of the Rails world is the so-called skinny controller/fat model approach

http://weblog.jamisbuck.org/2006/10/18/skinny-cont...

So the object in Rails might derive from ActiveRecord, which makes it pretty "basic" in the OO world, by the time you mixin some functionality, you're looking at just as rich an object as you'd build in most other languages, just with a few thousand less lines of code and a few hundred less files :)
# Posted By John Paul Ashenfelter | 8/21/07 4:51 PM
Just today, I started learning about DataMapper for Ruby: It looks promising from what I can tell. It has some benchmarks that look promising. It has less "magic" metaprogramming code than ActiveRecord, which is ok with me. It supports associations, though not as fully as ActiveRecord, from what I can tell. Please take my comments with a grain of salt; I am new to DataMapper.

Speaking to the main point of this blog post: One disadvantage of ActiveRecord (that I've run into personally) is that ALL columns in your database become attributes on your model. So if you want encapsulation (i.e. private attributes) in ActiveRecord, then you are out of luck. Encapsulation? In object oriented code? I know it is asking for a lot... ;)

So instead of (only) complaining, I wrote a patch for ActiveRecord:
which adds a method called attr_private. It passes the tests I wrote for it and would be interested in feedback of all sorts. (Yes, I've heard of attr_protected, but it does *not* really make a database column protected.)

Since the patch hasn't gotten much attention, I would guess (a) the Rails Core team is busy with more pressing issues, (b) my patch needs improvement, (c) my patch is missing the point of the active record pattern entirely (i.e. active record is not intended to encapsulate at all).

My pragmatic advice? If you want to be able to {encapsulate, rearrange, compose} database columns then check out DataMapper and see what you think. You might take a look at Merb while you are at it.
# Posted By David James | 9/28/07 11:34 PM
It appears as though the links got stripped out. For more information on DataMapper (a Ruby implementation), see datamapper dot org

If you are interested in my patch for 'attr_private' just put that term into google, or see:
dev dot rubyonrails.org / ticket / 8355
# Posted By David James | 9/28/07 11:36 PM
Robert Martin discusses consequences in a recent blog post: http://blog.objectmentor.com/articles/2007/11/02/a...
# Posted By Sammy Larbi | 11/3/07 2:34 PM
I think, this is kinda type HOW you start designing your app.

Your App is a section of real world and you try to create a miniworld that maps this section.

You extract the needed classes and their relation between them and then you think about persistence.

So, if I start such an App - I start with designing my database. And then I build my app above that.

I can't accept Robert Martin's argument, that it's "evil" so handle an ActiveRecord structure as if it's the object.
In my view - the ActiveRecord thing IS our object. It stands in our App and it is persistent in our database.
# Posted By Johannes | 1/10/08 7:17 AM
As Johannes said above. How do you build an application with no foundations? The database model is the whole foundation for your application. This does not mean it should be set in stone, before starting to develop the app, it can be an incremental process. Nonetheless, you need a very good idea of the underlying database.

How else do you start developing an application? GUI first? Even so, it is quite removed from the actual database, so it should not be a problem.

The consequences of A.R. is that you tend to forget SQL.
# Posted By tute | 1/17/08 3:58 PM
The foundation is the domain model, not the database. The database is nothing but a mechanism to persist objects. This is the whole problem with most people who praise the ActiveRecord approach: they start with the database, which should be the LAST thing to focus on. The database design should support the domain model, not the other way around.

There are plenty of ORM frameworks that let you "forget SQL" but don't rely on ActiveRecord. Handling CRUD operations or generic filter queries has never been the problem. Generating that is simple.
# Posted By Brian Kotek | 1/17/08 5:09 PM
BlogCFC was created by Raymond Camden. This blog is running version 5.9. Contact Blog Owner