Getting Started With DataMapper

DataMapper って結構いいのかもしれない...と思い,目下勉強中.
以下,超意訳です.あしからず.
原文: http://datamapper.org/doku.php?id=getting_started_with_datamapper

はじめに,もしヘルプが必要だと思った場合,Mailing List と IRC を通したアクティブなコミュニティのサポートがある.


さて想像してみよう.
私たちは,ブログアプリのためのモデルを用意している最中だ.
私たちはそれを,いい感じでシンプルにしておきたい.
最初に決めることは,私たちがモデルに何を求めているか?ということだ.
Post は与えられている.Comment もだ.But let's mix it up and do Category too. (←?)

Install DataMapper

もしあなたが RubyGems をインストールしているのであれば,コンソールを立ち上げ,いくつかのものをインストールしよう.
(お好みなら do_sqlite3 を do_postgres か do_mysql に置き換えよう)

sudo gem install do_sqlite3 dm-core

もし merb と一緒に使うのであれば,DataMapper の大部分が必要になるだろうから,afrench の作法の代わりに以下のことをするだろう.(←?)

sudo gem install datamapper

また,rspec, cucumber, hoe, launchy, json_pure のインストールが必要になるだろう.
(それらは gemspec から欠けているように思われる)

sudo gem install rspec cucumber hoe launchy json_pure


(2009/07/11 に変更されていますね.最新版は以下の通り.)

sudo gem install dm-more

Require it in your application

require 'rubygems'
require 'dm-core'
# 旧バージョン → require 'datamapper'

Specify your database connection

モデルを定義する前に,次の set を確認する必要がある.

# An in-memory Sqlite3 connection:
DataMapper.setup(:default, 'sqlite3::memory:')
# A Sqlite3 connection to a database file:
DataMapper.setup(:default, "sqlite3:///#{Dir.pwd}/test.db")
# A MySQL 4.x+ connection:
DataMapper.setup(:default, 'mysql://localhost/dm_core_test')
# A Postgres 8.2+ connection:
DataMapper.setup(:default, 'postgres://localhost/dm_core_test')

Note: DB 接続についてより具体的な方法を知りたいと思うかもしれない.
第 2 引数は,:host, :adapter, :database, :username, :password, :socket, etc... を含んだ Hash にすることができる.
これらは DB 仕様であるが,this ought to get you going.

Define your models

Post モデルは永続的である必要があるので,"include DataMapper::Resource" とする.
モデル名に関する規約は単数形を使うことである.
複数形の場合...があるわけではなく,単に規約である.あなたの好きなようにできる (← ?)

モデルには少なくとも 1 つの key property が含まれなければならない.

class Post
  include DataMapper::Resource
 
  # :serial を指定できる (auto-increment になり, ":key => true" が設定される):
  property :id,         Integer, :serial => true
  # ...もしくは "Serial" をしていする (これは,機能的に上記とまったく同じである):
  property :id,         Serial
  # ...または,ユーザ名のようにユーザが設定する key のためのオプションである :key を渡す
  property :name,       String, :key => true
 
  property :title,      String
  property :body,       Text
  property :created_at, DateTime
end
 
class Comment
  include DataMapper::Resource
  property :id,         Serial
 
  property :posted_by,  String
  property :email,      String
  property :url,        String
  property :body,       Text
end
 
class Category
  include DataMapper::Resource
  property :id,         Serial
  property :name,       String
end

Association

理想的には,これらの宣言は property やその他のことと一緒にクラス定義の内部でされるべきである.
しかし,デモンストレーションという目的のため,クラスを開くことにする.
(※「ホントは Post/Comment の定義に has や belongs_to を書いた方がよいけど,とりあえず別で書いておきますね.」といった感じか)

One To Many

Post は複数のコメントを持つことができるため,シンプルな 1 対多 の関係を設定する必要がある.

class Post
  has n, :comments
end
 
class Comment
  belongs_to :post
end
Has and belongs to many

Category は複数の Post を持てるし,Post も複数の Category を持つことができるため,一般的に "has and belongs to many" と呼ばれる 1:N:1 関係が必要である.

そこで,Post が Category へ分類された場合についてのちょっとしたメタデータを記録できる,2 テーブル間用 Join テーブルをラップするための即興モデルを設定する.

class Categorization
  include DataMapper::Resource
  property :id,         Serial
 
  property :created_at, DateTime
 
  belongs_to :category
  belongs_to :post
end

# 関係を定義するために Post と Category をもう一度開く.
class Post
  has n, :categorizations
  has n, :categories, :through => :categorizations
end
 
class Category
  has n, :categorizations
  has n, :posts,      :through => :categorizations
end

Set up your database tables

Post.auto_migrate!
Category.auto_migrate!
Comment.auto_migrate!
Categorization.auto_migrate!

これは,それぞれの property にしたがって各ストレージを定義するために必要な CREATE 文を発行するだろう.
次のようにもできる.

# Resource をインクルードした全てのクラスを Auto-migrate
DataMapper.auto_migrate!

Logging

クエリロギングの設定はシンプルである.

DataMapper::Logger.new(STDOUT, :debug) # :off, :fatal, :error, :warn, :info, :debug

あるいは,DataObjects のロギングをオンにして DataMapper::Logger の位置を指定することで,さらなる情報を取得できる.

DataObjects::Mysql.logger = DataObjects::Logger.new('log/dm.log', 0) 
DataObjects::Sqlite3.logger = DataObjects::Logger.new(STDOUT, 0)