Feed

Blog :: MongoDB or CouchDB for Rails

A tutorial focusing on MongoDB for Rails using MongoRecord.

A project I've been working on lately required me to accept results from a device called 'The Simulator' in XML format and write those results into a database to be displayed in a Rails app I've been building, 'The LMS' or 'Learning Management System'.

At first the concept seemed very simple, once I knew what the XML structure was going to look like I only needed to create a database table with a mirroring structure to hold the data.

After a few meetings we discovered that for each lesson the results passed back would be completely different, some tasks return 2 parameters others return 6. The names of these parameters also changed which meant that the only way to build this using a relational database was going to be to store the XML data for each task which seemed like a reasonable option.

Instead I decided to explore some alternative methods for storing unknown data types. I quickly came across 2 document-oriented databases, CouchDB and MongoDB.

Both of these databases look good, CouchDB seems to have a larger following as it's a bit older than MongoDB however MongoDB's website is and documentation is far more user friendly. I'll cover CouchDB in a separate article otherwise this on will get very long.

MongoDB

The first example I want to run through is MongoDB. MongoDB appealed to me more than CouchDB based on the clear documentation on the website. The install and set-up also looked so simple I thought it would be the easier to get going with.

Once you've downloaded MongoDB to your computer all you need to do is create a 'data/db/' folder scheme on your disk drive. For my this just sat in 'C:\data\db\'. This is the location your databases will be stored. Next in the bin folder where you downloaded MongoDB create a small windows batch file with the following line inside 'START mongod.exe --port 12345', this will save you having to use command prompt to load MongoDB every time you want to do some work, you can use whatever port number you want here.

Now MongoDB is installed and running you'll need to install the MongoDB Ruby driver. This can be done in 2 simple commands.

gem sources -a http://gems.github.com

and...

gem install mongodb-mongo

Now you've installed the MongoDB drivers for Ruby the next step is to install a Rails plug-in called MongoRecord. I chose MongoRecord as I assumed it would fit easier into a Rails project being that it's an implementation of ActiveRecord. There are actually several other ruby gems for dealing with MongoDB such as MongoMapper, MongoTree and merb_mongomapper to name a few.

To install MongoRecord just run the following command.

gem install mongodb-mongo_record

Now all the files are installed I'm going to create a quick and simple rails app to start testing that just contains notes.

rails document_databases

Next I just need to create a quick scaffold for my notes.

script/generate scaffold Note title:string body:string

Next we need to configure the Rails app to use MongoDB instead of the database stored in your 'config/database.yml' file. To do this we need to set-up a connection to MongoDB in our environment file and remove ActiveRecord from our Rails project.


RAILS_GEM_VERSION = '2.3.3' unless defined? RAILS_GEM_VERSION

require 'rubygems'
require 'mongo'
require 'mongo_record'
require File.join(File.dirname(__FILE__), 'boot')

MongoRecord::Base.connection = Mongo::Connection.new("localhost", 12345).db('mongodb_db')

Rails::Initializer.run do |config|
  config.frameworks -= [ :active_record, :active_resource, :action_mailer ]
  config.time_zone = 'UTC'
end

As you can see from the file we've included the 'mongo' and 'mongo_record' gems here and we're createing a new connection to a database called 'mongodb_db' on our localhost at port 12345. The only other amend to this file is the first line in the 'Rails::Initializer.run block where we're removing ActiveRecord, ActiveResource and ActionMailer libraries as we do not need them for this project.

Next we need to configure our notes model, this turned out to be really easy with MongoRecord. All you have to do here is name a collection, the fields and the name of the index.


class Note < MongoRecord::Base

    collection_name :notes
    fields :title, :body
    index :title

end

You only now need to remove the following line from the 'app/views/notes/new.html.erb' and 'app/views/notes/edit.html.erb' forms.

<%= f.error_messages %>

With MongoRecord it's that easy. You should now be able to use the basic app the same way you do with a normal ActiveRecord Rails app. However while MongoRecord is simple to set-up and easy to use, the specification of the fields makes the use of a document database almost pointless. Instead of specifying each time the 'title' and 'body' fields in my note model it would be nice to have the flexibility of adding newer fields as and when I need them.


Published: Tags: database, document database

2 comments

Fe68cca2a835f4f51d07cf54ef03d505?s=60&d=http%3a%2f%2fwww

Mike Dirolf

Great article - thanks! Just wanted to let you (and anybody else reading this) know that we've moved the gems from github to gemcutter, so the install process is a bit different (but just as easy) - this thread has the details: http://groups.google.com/group/mongodb-user/browse_thread/thread/6e11052b94c1535f#

Fe68cca2a835f4f51d07cf54ef03d505?s=60&d=http%3a%2f%2fwww

Mike DIrolf

Another note - MongoRecord (and I believe MongoMapper as well) allows you to add custom attributes to instances of your models that you're saving. So if you need to an attribute you can do so without updating your model (taking advantage of MongoDB's schema-free nature).

Add a comment

Twitter feed

Twitter_bird

Mobile-phone pocket watch - http://www.celsius-x-vi-ii.com/ Amazing design and technology.
Tweeted: 2 days ago

RT @dhh: Rails 3.0: It's ready http://bit.ly/bqyTHh - after two years of work & thousands of commits. What an amazing community achievement!
Tweeted: 4 days ago

Agile (content) feature 2: Form builder. Dynamically create forms that email, or save content to the database with optional auto responses.
Tweeted: 7 days ago