Mongoid試してみた

特に目先の目的はないんだけど、スキーマとデータを後から自由に、しかもメンテナンスストップせずに変更できそうな気がして MongoDB を動かしてみようと思い、Mongoid をちょっと触ってみた。

自分用のメモなので特に面白い話はないです、念のため。

Mongoidを使った開発の準備

MongoDBのインストール

省略

新規アプリ作成

rspec を使いたいので

rails new APP_NAME -T -O

で、作成。

できあがったアプリケーションのGemfile

assets とか省略して最低限こんな感じ。

gem 'mongoid'
gem 'bson_ext'

group :development, :test do
  gem 'rspec-rails'
end

で、これを

bundle instal

します。bson_ext はなくても動くみたいだけど、なんかいろいろメッセージが出てうるさかったのでインストールして黙らせた。

generatorを叩いて設定ファイル作成

mongoid のインストールが成功していれば

rails g mongoid:config

これで config/mongoid.yml ができる。これは中身いじらなくて ok. rspec の分は省略。

dbの場所確保とmongod起動task

MongoDB は SQLite3 のような組み込み用ではないので daemon を起こす必要がある。繊細な感じがしていやだったので以下のような rake task を用意した。

これは

db/mongodb/
config/mongo_develop.conf.erb

を作って、conf.erb の内容から conf を生成してこの conf を mongod -f に与えて起動するようになっている。

screen を起こして一つの window で mongod を、もう一つで rails server を起こすようにすると邪魔じゃないしタブの意図が明確になっていいんじゃないかと思う。mongoid.yml の配置以降は mongod 起きてないと rails コマンドがちゃんと機能しないかも。

少なくとも migration は migration 実行時に初めて DB に変更が加わるんだけど Mongoid の場合はその場で変更できるものは変更するらしい。したがって mongod が起きてないと generate や destroy は実行できない。

Modelの作り方

普通に generator を使う。上のセットアップを済ますと generate model は Mongoid の model 生成用 generator に差し替わっている。1

できるのはこんなモデル。

class Foo
  include Mongoid::Document
end

ただし、これだと timestamps 相当の field がない。ActiveRecord::Migration が標準で作るのと同じ感じの Model にするには以下のように作る。

class Bar
  include Mongoid::Document
  include Mongoid::Timestamps

  field FIELD_NAME, { option }
end

Mongoid はこんな感じで便利機能をイロイロ include できるらしいので一度確認しておくとよさげ。

cf. Play With Mongoid!

Mongoid + Dragonfly

ActiveRecord の場合は以前

今さらRails3メモ - 番外編その1: Paperclip and Dragonfly

で書いたように require するだけでいいんだけど、Mongoid の場合はもう一手間必要。

File: Mongo — Documentation by YARD 0.7.4

と言っても本家に書いてある通りで、

require 'dragonfly'

app = Dragonfly[:images]

...

# Allow all mongoid models to use the macro 'image_accessor'
app.define_macro_on_include(Mongoid::Document, :image_accessor)

MongoDataStore 使わないなら上の実質2行を initializer に加えるだけ。

感想

migration がないので最初のセットアップのテンポがいい。ActiveRecord のときは

  • migration の方に column を書く
  • Model に attr_accesible 定義や validation で column を書く
  • さらに管理画面に Typus を使ってると Typus で編集可能な column 定義書く

という感じで、

DRY !!!

って叫びたくなる。それが Mongoid + RailsAdmin だとだいぶ楽ちんな感じ。2

とは言え migration がないので逆に field 名変更は全 document に対して実行しなければいけない。rails runner でのバッチ処理の出番か。

もともとできるだけ生SQLは書かないようにしていた3し、別に RDBMS 脳でもないので Mongoid 縛りで MongoDB を使うのにはそれほど抵抗ないんじゃないかなーと思っている。まだ Relation 使ってないから join ねーよ!ってときの気持ちが分からないけど、ま、なんとかなるんじゃないかな?

参考

  1. ActiveRecordを使うgeneratorは active_record:model に退避されているので使おうと思えば使える。 

  2. RailsAdminについては別エントリで。 

  3. といっても凝ったことしようとすると書いた方が早かったりするんだけど 

More