2008年8月18日月曜日

Merb ことはじめ

Ruby には、Rails 以外にも様々な Web Application フレームワークがあります
今回はその内のひとつ、 Merb を試してみました。

Merb とは?

Merb (Mongrel + Erb) は Ruby で書かれた MVC フレームワークです。

「規約と DRY」の Rails は、何でもできる一方で、コアが必要以上に大きいフレームワークとなっています。このため、あるプロジェクトでは Rails は冗長すぎる可能性もあります。

一方、Merb が目指したのは「疑わしきは入れず」。
コアはあくまでシンプルに。必要なものを必要に応じて追加していくイメージのフレームワークです。
この点で、Merb の本家サイトではその特徴として、
  • Faster
  • Lighter
  • More Agile
を謳っています。

Welcome!

以下では、Merb 0.9.4 及び、ランタイムとして Ruby 1.8.6 を利用します。
まず、以下のコマンドでインストールをします。
$ sudo gem install merb --include-dependencies
続いて、Merb アプリケーション、hello_merb を生成します。
$ merb-gen app hello_merb
Generating with app generator:
[ADDED] hello_merb/test/test_helper.rb
[ADDED] hello_merb/public/stylesheets/master.css
.......
[ADDED] hello_merb/app/views/layout/application.html.erb

$ cd hello_merb

merb は以下のコマンドで一発で起動します。
$ merb
これで、http://localhost:4000/ にアクセスすると、Welcome! のページが表示されるようになります。

Hello, Merb!

次に Controller を利用して、Hello, Merb の文字列を表示させてみます。Merb には generator が装備されています。以下のコマンドから、hello コントローラを生成します。
$ merb-gen controller hello
Generating with controller generator:
[ADDED] app/controllers/hello.rb
[ADDED] app/views/hello/index.html.erb
[ADDED] spec/controllers/hello_spec.rb
[ADDED] app/helpers/hello_helper.rb
[ADDED] spec/helpers/hello_helper_spec.rb
Rails と異なり、Controller の名前の後ろに _controller はつきませんので注意。Hello, Merb を表示する方法は次の 2 通り。
  • app/views/hello/index.html.erb に文字列 Hello, Merb! と記述。
  • Hello Controller の index アクションを、以下のように変更
    class Hello < Application
    # ...and remember, everything returned from an action
    # goes to the client...
    def index
    "Hello, Merb!"
    end

    end
2 番目の方法において、アクションの実行結果のオブジェクトが HTTP レスポンスボディになることを利用しています。

これらの作業により、http://localhost:4000/hello/ にアクセスすると、"Hello, Merb!" が表示されます。

DataMapper を利用する

Merb のデフォルトの Object Relational Mapper: ORM は Rails と同じく ActiveRecord です。しかし、Merb の性質上、他の ORM を利用することができます。せっかくなので、今回は、ActiveRecord とは別の ORM、DataMapper を利用します。

DataMapper は、
  • 高速
  • スレッドセーフ
  • 高機能
を目標とした、Ruby で記述された ORM です。

まず、DataMapper の インストールです。
Merb 上で利用する場合、Edge DataMapper が必要です。
Edge DataMapper を以下のコマンドからインストールします。
$ sudo gem install addressable english rspec
$ mkdir -p ~/src
$ cd ~/src
$ sudo gem install sake
$ sake -i 'http://github.com/dkubb/dm-dev/tree/master/dm-dev.sake?raw=true'
$ sake dm:clone
$ cd dm
$ sake dm:install
※ 以下のコマンドでも DataMapper 自体インストールできます。 ただ、 Edge DataMapper をインストールしないと、Merb 上では DataMapper が上手く動作しませんでした。
$ gem install data_objects do_sqlite3 do_mysql dm-core 
さて、次に、 DataMapper を利用したアプリケーション、 dm_test を作成することにします。
先程作成した、hello_merb ディレクトリから一旦抜けてください。

ORM に DataMapper を利用したアプリケーション、 dm_test を以下のコマンドから作成します。
$ merb-gen app --orm datamapper dm_test
Generating with app generator:
[ADDED] dm_test/test/test_helper.rb
[ADDED] dm_test/public/stylesheets/master.css
[ADDED] dm_test/config/init.rb
....
[ADDED] dm_test/app/views/layout/application.html.erb
更に、config/database.yml.sample を生成します。
rake dm:db:database_yaml
これをコピーし、config/database.yml とし、データベースを環境に合わせ、以下のように設定します。
# This is a sample database file for the DataMapper ORM
development: &defaults
# These are the settings for repository :default
adapter: mysql
database: dm_test
username: dm_test_user
password: secret
host: localhost
次に、モデルを生成します。
$ merb-gen model user
Generating with model generator:
[ADDED] spec/models/user_spec.rb
[ADDED] app/models/user.rb
生成されたモデルを以下のように編集します。
class User
include DataMapper::Resource
property :id, Integer, :serial => true
property :name, String, :nullable => false
end
そして migrate。
rake dm:db:automigrate
ここまでできたら、merb -i (Rails での script/console) で model を操作してみます。
$ merb -i
~ Loaded DEVELOPMENT Environment...
~ Connecting to database...
~ loading gem 'merb_datamapper' ...
~ Compiling routes...
~ Using 'share-nothing' cookie sessions (4kb limit per client)

# User を生成
irb(main):001:0>user = User.new(:name => "Naofumi HAIDA")
=> #<User id=nil name="Naofumi HAIDA">

# 保存
irb(main):002:0> user.save
=> true

# 取得
irb(main):003:0> User.all
=> [#<User id=1 name="Naofumi HAIDA">]

# id 1 のユーザを取得
irb(main):004:0> User.get(1)
=> #<User id=1 name="Naofumi HAIDA">
このように、ユーザモデルを操作できるようになりました。同様にコントローラからモデルを操作することにより、アプリケーションができていきます。

DataMapper の repository 機能

DataMapper では複数の Database を簡単に使い分けることができます。先程の config/database.yml ファイルの repositories の項目に以下のように記述を追加します。
# This is a sample database file for the DataMapper ORM
development: &defaults
# These are the settings for repository :default
adapter: mysql
database: dm_test
username: dm_test_user
password: secret
host: localhost

# レポジトリの設定
repositories:
common:
adapter: mysql
encoding: utf8
database: dm_test_common
username: dm_test
password: dm_test_user
host: localhost
共通で利用する DB が別にある場合を想定して、common という名前の DB を設定してみました。これを以下のように利用できます。
# デフォルトで利用する DB からデータを取得
user = User.first
# 共通データベースからデータを取得
admin = Admin.first(:repository => repository(:common))
モデル単位でどこのリポジトリを使うか、を設定できますので、上記のように、普通のデータはデフォルトの DB に入れ、あるモデルは :common から取得する、という使い方もできます。

まとめ

本記事のように、Merb では必要に応じ、必要なライブラリを使いながらアプリケーションを構築していくことができます。また、Rails ライクにアプリケーションを作成できるので、Rails からの乗り換えもそれほど大変ではないかと思います。


※ 参考記事