Getting started with DataMapper

First, if you think you might need some help, there’s an active community supporting DataMapper through the mailing list and the #datamapper IRC channel on irc.freenode.net.

So lets imagine we’re setting up some models for a blogging app. We’ll keep it nice and simple. The first thing to decide on is what models we want. Post is a given. So is Comment. But let’s mix it up and do Category too.

Install DataMapper

If you have RubyGems installed, pop open your console and install a few things. (Substitute do_mysql with do_postgres if you’re into Postgres)

1 gem install data_objects do_sqlite3 do_mysql dm-core

Require it in your application

1 require 'rubygems'
2 gem 'dm-core'
3 require 'dm-core'

Specify your database connection

You need make sure this is set before you define your models.

1   # An in-memory Sqlite3 connection:
2   DataMapper.setup(:default, 'sqlite3::memory:')
3   # A MySQL 4.x+ connection:
4   DataMapper.setup(:default, 'mysql://localhost/dm_core_test')
5   # A Postgres 8.2+ connection:
6   DataMapper.setup(:default, 'postgres://localhost/dm_core_test')

Define your models

The Post model is going to need to be persistent, so we’ll include DataMapper::Resource. The convention with model names is to use the singular, not plural version…but that’s just the convention, you can do whatever you want.

 1 class Post
 2   include DataMapper::Resource
 3   property :id,         Integer, :serial => true
 4   property :title,      String
 5   property :body,       Text
 6   property :created_at, DateTime
 7 end
 8 
 9 class Comment
10   include DataMapper::Resource
11   property :id,         Integer, :serial => true
12   
13   property :posted_by,  String
14   property :email,      String
15   property :url,        String
16   property :body,       Text
17 end
18 
19 class Category
20   include DataMapper::Resource
21   property :id,         Integer, :serial => true
22   property :name,       String
23 end
24 

Associations

Ideally, these declarations should be done inside your class definition with the properties and things, but for demonstration purposes, we’re just going to crack open the classes.

One To Many

Posts can have comments, so we’ll need to setup a simple one-to-many association between then:

1 class Post
2   has n, :comments
3 end
4 
5 class Comment
6   belongs_to :post
7 end

Has and belongs to many

Categories can have many Posts and Posts can have many Categories, so we’ll need a 1:N:1 relationships commonly referred to “has and belongs to many”. We’ll setup a quick model to wrap our join table between the two so that we can record a little bit of meta-data about when the post was categorized into a category.

 1 class Categorization
 2   include DataMapper::Resource
 3   property :id,         Integer, :serial => true
 4   
 5   property :created_at, DateTime
 6   
 7   belongs_to :category
 8   belongs_to :post
 9 end
10 
11 # Now we re-open our Post and Categories classes to define associations
12 class Post
13   has n, :categorizations
14   has n, :categories, :through => :categorizations
15 end
16 
17 class Category
18   has n, :categorizations
19   has n, :posts,      :through => :categorizations
20 end
21 

Set up your database tables

1 Post.auto_migrate!
2 Category.auto_migrate!
3 Comment.auto_migrate!
4 Categorization.auto_migrate!

This will issue the necessary CREATE statements to define each storage according to their properties.

You could also do:

1 DataMapper.auto_migrate!