Rails で MongoDB を使ってみた
2010/03/23
Ubuntu Karmic (9.10) で MongoDB + mongoid を使って簡単な Rails アプリケーションを作ってみました。
MongoDB とは、最近注目を集めつつあるドキュメント指向データベースの一種。mongoid は MongoDB にアクセスするための RubyGems。
参考資料:
次の行を /etc/apt/sources.list の末尾に追加
deb http://downloads.mongodb.org/distros/ubuntu 9.10 10gen
aptitude で MongoDB をインストール。
% sudo aptitude update % sudo aptitude mongodb-stable
Windows を含む他の OS でのインストール手順については、Quickstart - MongoDB をご覧ください。
動作確認。
% mongo MongoDB shell version: 1.2.4 url: test connecting to: test type "help" for help > db.foo.save( { a : 1 } ) > db.foo.find() { "_id" : ObjectId("4ba7859134532c5d5844387e"), "a" : 1 } > exit bye
mongod の停止と開始。
% sudo service mongodb stop % sudo service mongodb start
ここからは、http://mongoid.org/docs/installation に従って、Rails アプリケーションをセットアップ。
gem で mongoid, mongo_ext をインストール。mongo_ext は高速化のための拡張ライブラリ。
% sudo gem install mongoid % sudo gem install mongo_ext
新規アプリケーション papagena を作成。
% rails papagena % cd papagena
config/environment.rb に次の行を追加(Rails::Initializer.run do |config| ... end の間に)。
config.load_paths += %W( #{RAILS_ROOT}/app/documents ) config.gem "mongoid", :lib => "mongoid", :version => "1.2.14"
config/database.mongo.yml
development: host: localhost database: papagena_dev
config/initializers/mongoid.rb
File.open(File.join(RAILS_ROOT, 'config/database.mongo.yml'), 'r') do |f| @settings = YAML.load(f)[RAILS_ENV] end Mongoid.configure do |config| name = @settings["database"] config.master = Mongo::Connection.new.db(name) end
app/documents ディレクトリを作成。
% mkdir app/documents
app/documents/person.rb
class Person include Mongoid::Document field :first_name field :last_name def full_name "#{first_name} #{last_name}" end end
public/index.html を削除。
% rm public/index.html
config/routes.rb
ActionController::Routing::Routes.draw do |map| map.root :controller => 'people' map.resources :people end
app/controllers/people_controller.rb
class PeopleController < ApplicationController def index @people = Person.all end def show @person = Person.find(params[:id]) end def new @person = Person.new end def edit @person = Person.find(params[:id]) end def create @person = Person.new(params[:person]) if @person.save redirect_to @person else render :action => 'new' end end def update @person = Person.find(params[:id]) @person.attributes = params[:person] if @person.save redirect_to @person else render :action => 'edit' end end def destroy @person = Person.find(params[:id]) @person.destroy redirect_to :people end end
app/views/index.html.erb
<h1>People#index</h1> <ul> <% @people.each do |person| %> <li> <%= link_to h(person.full_name), person %> <%= link_to 'Edit', [ :edit, person ] %> <%= link_to 'Delete', person, :method => :delete %> </li> <% end %> </ul> <%= link_to 'New person', [ :new, :person ] %>
app/views/show.html.erb
<h1>People#show</h1> First Name: <%= @person.first_name %><br /> Last Name: <%= @person.last_name %><br /> <%= link_to 'List', :people %>
app/views/new.html.erb
<h1>People#new</h1> <% form_for @person do |f| %> <%= f.label :first_name %> <%= f.text_field :first_name %><br /> <%= f.label :last_name %> <%= f.text_field :last_name %><br /> <%= f.submit %> <% end %>
app/views/edit.html.erb
<h1>People#edit</h1> <% form_for @person do |f| %> <%= f.label :first_name %> <%= f.text_field :first_name %><br /> <%= f.label :last_name %> <%= f.text_field :last_name %><br /> <%= f.submit %> <% end %>
アプリケーションを起動。
% ruby script/server
お、動いた!
気付いたこと。
- データベースを create するという操作は不要。いきなり使える。
- マイグレーションも不要。
- オブジェクトの id は 4ba792d257e5fb15cc000001 のような形式の値。
- したがって、show アクションの URL は http://localhost:3000/people/4ba792d257e5fb15cc000005 のようになる。
これは面白い。
MongoDB の説明によれば、トランザクションがない代わりに、負荷分散がやりやすい。つまり、お金やポイントの取り扱いには向かないけど、いわゆる「コンテンツ」を大量に保存するなら RDBMS より向いているかもしれない。例えば、大規模なコミュニティサイトを構築したいなら、ポイント関連のデータを MySQL に保存して、ユーザー間のメッセージなどを MongoDB に保存するといった使い分けをすればいいわけだ。