Merb and Data Mapper

November 16, 2007

A couple of new frameworks making waves in the Ruby community are Merb and Data Mapper. Merb and Data Mapper seem to go together like peanut butter and jelly in that Merb gives you pretty much everything Rails gives you except for an ORM framework, and Data Mapper is an ORM framework like Active Record.

Data Mapper has a fantastic Why Data Mapper? page. I love this page because it assumes you the reader are a Ruby on Rails web developer, so you know Active Record, and you want to know why you'd want to use Data Mapper instead of Active Record. After reading that page, I was definitely intrigued. It's amazing what good documentation can do for the success of a framework. Merb has documentation on the differences between Merb and Rails as well.

The most obvious difference that jumps out at you between Active Record and Data Mapper is that in the Data Mapper, you define the properties (a.k.a fields, attributes, columns) of your models inside the model itself, as opposed to Active Record, where you define no properties in your model and reflect the properties from the columns in your database. This has long been a point of contention for many developers critical of Rails.

The most obvious difference between Rails and Merb is that with Merb, controller actions always return the data that is to be sent to the client. A Merb action can simply return a String, or it could return a File, and IO or even a Proc. That sounds cool.

It will be interesting to see if Merb/Data Mapper gain popularity in the Ruby community. Rails is a full-stack solution, where as Merb is a MVC framework and leaves it up to you to choose an ORM framework and Data Mapper is just an ORM, not tied to any one MVC framework. This is more like the Java web framework world, where you have MVC frameworks like Struts, Stripes, etc. and ORM frameworks like Hibernate, and you glue them all together with something like Spring or Guice. The difference here is that you glue them together with Ruby, still no XML or Annotations needed.

One thing I thought I liked about Rails is that it's the only web framework people in the Ruby community use to build web apps. In the Java world, managers and business types would say "We're a Java shop" or "We're building our app in Java", but the reality is that there are so many different frameworks and saying you are building it in "Java" could mean one of a hundred different things. That might really mean "JSF/Struts 2/Spring/Hibernate" or "Freemarker/Stripes/Guice/iBatis". Matt Raible has basically built his entire career around analyzing all the different options there are for Java web frameworks, as well as developing a meta-framework to help tie them all together. Up until now, on the Ruby side of things, if someone says we're building an app with Ruby on Rails, you know what you are talking about.

But it seems this could be the start of trend, where we get more frameworks within the Ruby community, which is a good thing because you can make choices, but on the other hand it could start to fragment the community. Overall I think it's a win and the reality you come to realize after developing with Rails for a year or so is that Ruby is really the thing that makes the whole thing go and that knowledge is easily portable to other Ruby frameworks. To make it even easier, Merb and Data Mapper both have many of the same concepts as Rails, so I can't imagine the learning curve of switching from one to the other to be particularly steep.

Another crazy idea is that with specialized frameworks like Merb and Data Mapper that are meant to be just one part of a stack rather than the full stack like Rails, and JRuby becoming a legitimate option, you could start to see some weird hybrid Ruby/Java apps, like Merb+Hibernate, or Stripes+Data Mapper. I doubt that would be common, but you could do it.

So talk is cheap, let's get something going. To install Merb and Data Mapper, I followed these instructions for setting up Merb and Data Mapper.

sudo gem install merb --include-dependencies
sudo gem install datamapper
sudo gem install ruby2ruby --include-dependencies
sudo gem install merb_datamapper
cd /usr/local/lib/ruby/gems/1.8/gems/datamapper-0.2.3
sudo bash -c "ARCHFLAGS='-arch i386' rake dm:install:mysql"

Believe it or not that actually worked for my on my Macbook. That last step just outputs the following if it works:

(in /usr/local/lib/ruby/gems/1.8/gems/datamapper-0.2.3)

Here's to hoping I can just do this at some point in the future:

sudo gem install merb_datamapper_mysql --include-dependencies

But you can't for now. So I continued following the instructions and got this error when I tried to run rake:

paulbarry@paulbarry: ~/projects/foo $ rake
(in /Users/paulbarry/projects/foo)
Using pure ruby JSON lib
rake aborted!
no such file to load -- json/pure
/Users/paulbarry/projects/foo/rakefile:10
(See full trace by running task with --trace)

Why didn't gem install merb --include-dependencies install json and json_pure for me if they are required dependencies? Good question, I don't know, but we'll just install them now to get things going:

sudo gem install json json_pure

So after that, everything goes off without a hitch. Picking up where the instructions left off, let's at least create a hello world app. Create a file in app/controllers called hello_world.rb with the following contents:

class HelloWorld < Application
  def index
    "<h1>Hello, World!</h1>"
  end
end

Go to http://localhost:4000/hello_world and bask in the glory of your fist Merb web application. This should seem familar, except for the fact that you are naming it HelloWorld instead of HelloWorldController. How do you avoid namespace collisions when you have a User controller and a User model? Good question, I'll let you know when I find the answer.

So as promised, you can just return a string and that's when gets rendered in the browser. But you don't want to do that for real, so let's render a template. Create a file app/views/hello_world/index.html.erb and put the html in there. Change the index method to just call render, like this:

class HelloWorld < Application
  def index
    render
  end
end

And there's our hello world with a template. Ok, so what about data mapper? So step one is create file in app/models called foo.rb with the following contents:

class Foo < DataMapper::Base
  property :bar, :string
  property :created_at, :datetime
  property :updated_at, :datetime

  validates_presence_of :bar
  validates_length_of :bar, :minimum => 1
end

This also should make sense if you are Rails developer. The only difference is that we are defining our properties in the class, rather than in a migration. To create our table and a test record, start the merb console, which you do by executing merb -i, and then enter these commands:

irb(main):004:0> DataMapper::Base.auto_migrate!
=> [Foo]
irb(main):005:0> Foo.create(:bar => 'Hello, World!')
=> #<Foo:0x22c5964 @new_record=false, ...

Ok, so them we modify our controller and view to use this:

class HelloWorld < Application
  def index
    @foo = Foo.first
    render
  end
end

and:

<h1><%= @foo.bar %></h1>

And there we go, Merb and Data Mapper working together as one.

Posted in Technology | Tags Merb, Ruby, Rails, DataMapper

Comments

1.

Paul:

Thanks for the link to my post!!

Good write up too.

I'm hoping to do a follow up article that shows how to generate a basic application, but I want to wait until migrations are fully implemented in DataMapper as I feel that an important part of a good process.

# Posted By Justin Pease on Saturday, November 17 2007 at 1:32 PM

2.

Hi!

Nice post! I've a question. I have a User model, and a User controller. In rails the controllers get a Controller suffix for avoid name collision. In merb my controller and model get the same class name, and the server stops at boot. Are there any solutions for this problem, or use different name for controller, for example UserManager?

Thanks

# Posted By Nucc on Monday, February 25 2008 at 10:38 AM

3.

@Nucc: If you are doing a RESTful design, so your controller is Users and the model is User, so there is no name collision.

# Posted By Paul Barry on Monday, February 25 2008 at 12:23 PM

4.

Yes, it's true! :) You persuade me! ;)

Do you think merb can be strong competitor of Rails? Because rails is a huge framework.

I feel the main drawback of these frameworks is hosting. Until they don't solve this problem, these frameworks don't get more popularity.

# Posted By Nucc on Monday, February 25 2008 at 1:19 PM

5.

I do think Merb can be a strong competitor of Rails on one of the main reasons is hosting. You get more bang for your buck, so to speak with Merb. People say Rails doesn't scale, which isn't true, but it does use more RAM and CPU to scale, which has some cost. Merb will handle requests fast, and more importantly, more concurrent requests with less RAM and CPU than Rails, because it is a framework designed to be lean and fast. One of the ways it will be able to do this is because it is threadsafe, which Rails is not.

Also, the Merb team is working on a mod_rubinius, which would be an apache module to allow you to setup Merb apps just as easily as your can set up PHP.

Merb and DataMapper both have a long way to go to be bug free and feature complete with Rails, but that gap is closing everyday. By this time next year, I expect Merb+DataMapper to be being used in a lot of production Ruby web application instead of Rails.

# Posted By Paul Barry on Monday, February 25 2008 at 4:39 PM

6.

So be it!

Thanks!

# Posted By Nucc on Monday, February 25 2008 at 4:45 PM

7.

Hi, Paul

Fancy finding you in top 5 for Google searching on Merb. Nice write up. Ya missed the step about enabling DataMapper in Merb!

I found another excellent tutorial covering this here:

http://codingbitch.com/p/comboy/merb%20+%20datamapper%20+%20noob:%20quick%20start

Michael

# Posted By Michael on Thursday, March 6 2008 at 7:41 PM

8.

Hi guys, I wrote an article about setting up Merb 0.9, DataMapper 0.9, Subversion, and Nginx on a SilverRack host.

http://aaron.aaron033.com/articles/2008/06/27/merb-datamapper-nginx-upload-progress-rack-mongrel-subversion-on-silverrack-vps

Enjoy your adventures!

# Posted By Aaron Qian on Monday, June 30 2008 at 1:09 PM

9.

I think this guy stole your post and put it on his site word for word!

http://chandrahasreddy.blogspot.com/2008/01/merb-and-data-mapper.html

# Posted By ha on Friday, January 30 2009 at 11:52 AM

Comments Disabled