Jul
11
2005

Rails vs Plone – The battle of design patterns

When I spent some time playing with Ruby on Rails back in May, I could not help but wish that Rails (or something like it) was around when I was first building and prototyping the Plone-based “MyThoughtWorks” time and expense system. 18 months earlier, I picked Plone because it was written in Python and had a beautiful user interface. However, a bulk of my pain with the current MyThoughtWorks code base in Plone is all the CRUD (domain object< ->sql< ->database) code we had to roll by hand when I decided to store the data in Oracle, instead of the Zope Object Database (ZODB). Ruby on Rails’ Active Record might have made that CRUD pain go away.

Using Plone’s Archetypes with its default database storage option was not an option for me, since meta-data would still reside in the Zope database. I wanted all (not just some) of my data to live in my relational database. With no “important” data living in my ZODB, I can do Zope/Plone development “The Right Way” and throw out the ZODB with every new release.

Plone does offer a plug-in, called “Ape”, that can handle my database mapping preferences. Shane Hathaway, Ape’s author, credits ThoughtWorks own chief scientist Martin Fowler and his patterns book as inspiration for his code. Rails’ David Hansson also credits Martin’s same book for the origins of Active Record. The big difference, however, is that Shane implemented the Data Mapper pattern. Ape’s implementation of Data Mapper is complex to understand, complex to use, complex to extend, and uses lots of ugly XML configuration files. Ape is complex because the Data Mapper pattern is complex– it can handle all possibilities. Rails’ Active Record, on the other hand, is a breath of fresh air. I totally agree with David Hansson for his reasons for going with Active Record instead of Data Mapper. For the kind of internal business apps that I get paid to build at ThoughtWorks, Active Record hits the sweet spot, and Data Mapper is over-kill.

SQLObject is probably Python’s closest equivalent to Rails’ Active Record. Although, Adrian Holovaty tells me his Django framework also includes an Active Record-like ORM. I’m looking forward to checking out Django when it gets released later this week.

Anyway, it’s fun to see implementations of the ideas* in Martin’s book battle each other in the open source marketplace. And it’s also fun knowing I work for the same company as the guy who provided some of the gunpowder.

*I must note that Martin would be the first to comment that he didn’t invent the gunpowder– err– the design patterns– in his book. He expertly packaged and polished them, and framework developers like David Hansson and Shane Hathaway quickly took notice.

posted in python, rails by Jason Huggins

4 Comments to "Rails vs Plone – The battle of design patterns"

  1. Sam Newman wrote:

    Of course don’t forget that usign ActiveRecord couples your domain objects to the underlying DB – you cannot test your domain objects without testing your DB. Many of the Rails’ people get excited by doing things like running SQLlite against a RAM disk to speed their tests up, rather than asking the question’Why not just decouple the models from the DB?’.

    To my mind, on a moderately complex system (which to be fair is certainly not rails’ sweet spot) you’d need a seperate repository layer

  2. scooviduvoctagon wrote:

    I’ve been wondering –

    What are the perceived benefits of Zope’s ZODB?

    And when in what sorts of instances is Zope’s ZODB not appropriate? ( For instance why had the author decided not to store any data whatsoever in the object database, but instead opted fully for an rdbms? )

  3. mike bayer wrote:

    just because Ape is a very difficult and hard to configure Data Mapper algorithm, doesnt mean Data Mapper is intrinsically complicated. It just means Ape is complicated.

    All datamapper essentially means is that your database metadata and code for dealing with that metadata is decoupled from your domain objects. active record and datamapper both have the need to know about your database schema, so some kind of configuration is needed in both cases; the trick is making the configuration as easy and sparse as possible.

    All you really need is a good example of Data Mapper, implemented in a sparse “ruby/python” style, which would begin showing those people struggling to build large and complicated applications with Active Record the “light at the end of the tunnel”.

    (of course, therein lies the challenge…)

  4. Jeff Shell wrote:

    A big chunk of the problem with Zope 2 based object-relational mapping (and perhaps why Ape is so difficult) is that there can be a lot of arbitrary attribute assignment going on. Ape goes through great leaps to map all of the many aspects of an individual object across many tables, because a direct one-to-one mapping is not the way to go in Zope 2. There’s things like title, id, bobobasemodificationtime, assorted properties, and on and on and on. In Plone, there’s all of the Dublin Core metadata to work out. Ape is a very well written system, but it’s in a different problem space (I believe) than products like ActiveRecord and SQLObject. They’re all similar in that they do object-relational mapping, but Ape is really more of a full abstract persistence mechanism, allowing alternate marshalling types (flat and understandable files, for instance).

    The situation should be much better in Zope 3. There are is a much smaller inheritance hierarchy imposed on model objects – most of the times, it’s just ‘Persistent’ and/or ‘Contained’. And with things being interface driven, you could replace an implementation of a model object with a SQLObject managed one. There’s a suppport package for Zope 3 for this:

    http://codespeak.net/z3/sqlos/

    I don’t know how complete it is, but it looks fairly comprehensive and is a good example of how extensible Zope 3 can be by providing SQL backed containers and traversers that should fit right into Zope 3 with a minimal amount of effort.

 
Powered by Wordpress and MySQL. Theme by openark.org