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!