Rails3 対応 MongoDB ORM、Mongoid 詳解―ドキュメント

インストールに引き続き、ドキュメントを解説します。


ドキュメントは Mongoid のコアオブジェクトであり、データベースに永続化したい全てのオブジェクトは、Mongoid::Document をインクルードしてください。MongoDB でのドキュメントは、BSON オブジェクトとして表現されており、これは Ruby のハッシュや JSON によく似ています。Mongoid のドキュメントは、データベースのコレクションに格納されるか、他のドキュメントにエンベッドされ階層化された形で格納されます。Mongoid ではエンベッドされたオブジェクトもモデルとして表現できるという意味です。

ドキュメント定義

Person を表すシンプルなモデルを考えてみましょう。Person は、first name と last name と middle initial を持ちます。Person オブジェクトにフィールドを設定することにより、これらのアトリビュートを定義することができます。フィールドのデフォルトの型は String になります。

app/models/person.rb

class Person
  include Mongoid::Document
  field :first_name
  field :middle_initial
  field :last_name
end

このモデルは以下のコマンドでも作成できます。

$ rails generate model Person first_name:string middle_initial:string last_name:string


文字列以外の型については明示的に指定しなければなりません。Mongoid で使用できる型は、Array, BigDecimal, Boolean, Date, DateTime, Float, Integer, String, Symbol, Time となります。BigDecimal はデータベース上では String として格納されますが、プログラム側では BigDecimal として扱えます。

app/models/person.rb

class Person
  include Mongoid::Document
  field :birthday, :type => Date
end


フィールドは :default オプションにより、デフォルト値を設定できます。フィールドの型に必ず一致するようにして下さい。また、lambda を使用することも出来ます。

app/models/person.rb

class Person
  include Mongoid::Document
  field :blood_alcohol_level, :type => Float, :default => 0.0
end

ドキュメントのインスタンス

ドキュメントは、new を呼び、インスタンス化します。この時ハッシュを引数に取ります。もし存在しないフィールドがハッシュの属性に含まれていた場合、例外を上げます。また、ハッシュを引数に取る代わりに、ブロックの内部で設定することもできます。

person = Person.new(:first_name => "Ludwig", :last_name => "Beethoven")

person = Person.new do |p|
  p.first_name = "Ludwig"
  p.last_name = "Beethoven"
end

フィールドアクセスのコントロール

attr_protected を使うことで、ハッシュで一括して更新する際に、アトリビュートを保護することができます。逆に、attr_accessible は逆に、設定されてる値をセット可能に、その他を保護することができます。ActiveRecord のものと同様です。これらは、フォームの更新などから、重要なフィールドが思わぬ値をセットされないようにするためにあります。

attr_protected を使った場合、他のすべてのフィールドは、ハッシュで一括して、値をセットできます。

class Person
  include Mongoid::Document
  field :first_name
  attr_protected :_id
end

attr_accessible を使った場合、その他全てのフィールドは、ハッシュで一括しては、値をセットできません。

class Person
  include Mongoid::Document
  field :first_name
  field :last_name
  attr_accessible :first_name, :last_name
end

ダイナミックアトリビュート

Mongoid はデフォルトでは、ダイナミックアトリビュートをサポートします。ダイナミックアトリビュートは、フィールドがドキュメントで設定されてない時でも、値を取得・設定・永続化できるようにします。ただし、ドキュメントクラスのパブリックメソッドなどと重複する名前は使用することができません。


ダイナミックアトリビュートは次の例のように使用できます。

アトリビュートがドキュメントに存在する場合、Mongoid は、通常のゲッター・セッターメソッドを提供します。例えば、Person が gender アトリビュートを含む場合です。

person[:gender] = "Male"
person.gender # => "Male" を返す
person.gender = "Female" #=> gender に "Female" をセット

アトリビュートがドキュメント内に定義されてない場合、Mongoid はゲッター・セッターメソッドを提供せず、通常の method_missing を呼び出します。ダイナミックアトリビュートを使うには、他のアクセサメソッド( = )もしくは( read_attribute と write_attribute )を使わなければなりません。

person[:gender] # => returns nil
person[:gender] = "Male" # => gender に "Male" をセット

person.read_attribute(:age) # => returns nil
person.write_attribute(:age, 35) # => age に 35 をセット

予約された名前

もし、予約された名前とドキュメントのフィールド名が衝突した場合、例外が上がります。予約された名前の一覧は、Mongoid.destructive_fields でみることができます。


ドキュメントについては、以上になります。