DataMapper

I often find myself wishing for a simple complete code example for a new tool, so here you go. DataMapper is an Object Relational Mapper (ORM) gem for Ruby based projects. It uses the active record design pattern, after which the ActiveRecord gem, popularized by Rails, is so accurately named. I’ll leave the details of what all that means to your own research, but in short, DataMapper is a tool intended to ease the use of databases in your Ruby applications, so you have to spend less time thinking in terms of SQL queries and can spend more time manipulating your objects.

require 'rubygems'
require 'dm-core'
require 'dm-migrations'

DataMapper::Logger.new($stdout, :debug)
DataMapper.setup(:default, 'sqlite://' +
                           Dir.pwd + '/dm.db')

class DmTest
  include DataMapper::Resource
  property :id,     Serial
  property :name,   String
  property :whatever,  Text
end

DataMapper.auto_upgrade!
DataMapper.finalize

a = DmTest.new(:name => 'Bob',
               :whatever => 'whatever, dude')
a.save!

DmTest.all.each do |item|
  puts item.name
  puts item.whatever
end

Now what say we give you a breakdown of what’s going on here. First off, you’re going to have to have the usual stuff installed, Ruby, RubyGems, and SQLite along with any development headers. Once that’s done you’ll also need to install a few gems to work with:

sudo gem install sqlite3-ruby \
datamapper dm-core dm-sqlite-adapter

Alright, looking good. If you want to test that everything’s up and running just drop the code in the box up top in a .rb file and run it with Ruby. An SQLite database should appear in the directory you ran the program in, and it will have one record in it. (More if you run the program more than once.) Now let’s take a closer look at the code. We start with standard requirements to pull in the tools we’re using:

require 'rubygems'
require 'dm-core'
require 'dm-migrations'

Now things start getting a little more interesting. We are assigning the DataMapper logger to standard out, so that anything potentially useful it wants to tell us will get printed to the command line. Otherwise, who knows where the information will end up?

DataMapper::Logger.new($stdout, :debug)

Next we tell it what database to hook up to. Here I’ve elected to drop it into the directory you are running from. Dir.pwd just gets the current directory, which gets patched into the path for the sqlite database we will be using.

DataMapper.setup(:default, 'sqlite://' +
                           Dir.pwd + '/dm.db')

And here we have the class whose properties will be stored in the database. Pay particular attention to the include line, which pulls in all the methods necessary to bind this object to records in the database tables. property is then used to indicate which attributes of the object will be mapped, along with their data types. Serial indicates an auto-incrementing field. The rest are fairly self-explanatory.

class DmTest
  include DataMapper::Resource
  property :id,     Serial
  property :name,   String
  property :whatever,  Text
end

Here we have the auto_upgrade! method, which automatically makes changes to your database to accommodate changes in the model. This is similar to the auto_migrate! method, except for the fact that auto_migrate! wipes out the existing data in your tables with extreme prejudice. auto_upgrade! does its best not to hurt your data.

DataMapper.auto_upgrade!

And finally, we finalize our class. The rest was just talk–this is where the work really happens. When you finalize you classes DataMapper looks it all over, makes sure it’s valid, and makes whatever changes need to be made to the database. No looking back now.

DataMapper.finalize

Last, we get to play with it. The new method creates an instance of the object in memory. When you’re ready to see it memorialized in your database you can call the save! method.

a = DmTest.new(:name => 'Bob',
               :whatever => 'whatever, dude')
a.save!

DmTest.all.each do |item|
  puts item.name
  puts item.whatever
end

That’s it. Go have fun!

Tags: , ,

Leave a Reply

You must be logged in to post a comment.