DataMapper – Competition for ActiveRecord?

When Ruby on Rails first hit the scene, what attracted many of us to it was ActiveRecord. By providing a declarative syntax for describing relationships, validations, and callbacks it provided an elegance to model code that makes programming a lot more fun. Over the past couple of years ActiveRecord has received a lot of love, with has_many :through and improved caching options being the key additions I’ve enjoyed. But despite all that it’s given, ActiveRecord is clearly not the last word in Object Relational Mappers and it’s been good to see increased attention for some alternative Ruby ORMs such as DataMapper.

DataMapper shares a lot of syntax with ActiveRecord but promises a few new features, such as a more succinct find syntax, eg.

  # Find first entry in my_objects table
  MyObject.find(:first) # ActiveRecord
  MyObject.first        # DataMapper

  # Find all entries in my_objects table
  MyObject.find(:all)   # ActiveRecord
  MyObject.all          # DataMapper

and perhaps more usefully, improved finder options. Edited from the DataMapper site:

# 'gt' means greater-than. We also do 'lt'.
Person.all(:age.gt => 30)

# 'gte' means greather-than-or-equal-to. We also do 'lte'.
Person.all(:age.gte => 30)
Person.all(:name.not => 'bob')

# If the value of a pair is an Array, we do an IN-clause for you.
Person.all(:name.like => 'S%', :id => [1, 2, 3, 4, 5])

# Does a NOT IN () clause for you.
Person.all(:name.not => ['bob','rick','steve'])

You can approximate that functionality with some Rails plugins, and of course you can use the :conditions parameter to an ActiveRecord finder to do the same queries, but there’s something nice about being able to do it all in Ruby. (You can also fall back to ActiveRecord like syntax)

Most uses of DataMapper I’ve seen so far have been standalone, or in conjunction with merb, but I decided to give it a try by converting an existing rails app. Given how much similarity there is in syntax it seemed like it would be fairly easy to convert a few models and see how it compared. Unfortunately, it’s not that easy.

It’s pretty rare to build a rails app without plugins, and most plugins that affect models do so by extending ActiveRecord::Base. Since by using DataMapper you’re breaking away from ActiveRecord::Base, those plugins won’t work without invasive surgery. Similarly, DataMapper doesn’t support AR’s validation syntax and while it will soon have validations of its own, it looks unlikely that they’ll be compatible. It might well be possible to write a plugin that makes many other plugins work by examining ActiveRecord::Base.extended_by, and that could provide a translation layer to allow ActiveRecord validations to work with DataMapper, but that begins to be a lot of work for very little return.

Where DataMapper may really help Rails developers is in introducing more competition into the Ruby ORM world. By taking some radically different design decisions, particularly with regards to migrations and column specifications DataMapper allows us to see a different, but similarly elegant way of doing things, and hopefully ideas will percolate back into ActiveRecord just as AR has clearly inspired DataMapper. Personally I am looking forward to using DataMapper in my next non-rails ruby project, but found the exploration a useful reminder of how much of rails’ success is in its coherency as a stack.

Tags: , , , , ,

2 comments

  1. James, thanks for the kind words. It looks like some of the complaints are due just to my terrible lazy documentation efforts. πŸ˜‰

    DataMapper has actually had validations for many months. Originally it had it’s own mostly AR compatible syntax, but that was later replaced with the Validatable gem. (Which is also very similar to AR.)

    A number of useful things AR does with plugins are actually built into DM as well such as methods similar to acts_as_list, acts_as_tree (and with the way DM works, this is the only tree-like plugin you’ll ever need πŸ˜‰ ) and acts_as_paranoid.

    The downside is that some areas are a little crufty right now, and svn-trunk is really the only good way to go. But… That’ll be changing RSN. We’re shooting for 1.0 before MWRC, so there’s going to be much gnashing of teeth in the mean-time. πŸ˜‰

  2. Thanks for the comments Sam. It’s good to hear that things are moving forward and I’ll look forward to trying out a 1.0 release before too long :)