Docs Menu
Docs Home
/ / /
Mongoid
/

フィールドの動作をカスタマイズする

項目一覧

  • Overview
  • デフォルト値の指定
  • ストレージ名の指定
  • フィールド エイリアス
  • フィールドの再定義
  • カスタムIDフィールド
  • キャストできない値
  • カスタム ゲッターとセッター
  • 読み取り専用属性
  • フィールドのローカル化

このガイドでは、Mongoid モデルのフィールドの動作をカスタマイズする方法を学習できます。

default オプションを使用して、フィールドをデフォルト値を持つように設定できます。 デフォルトのフィールド値は固定値または Proc 値のいずれかです。

次の例では、 stateフィールドに固定のデフォルト値を指定します。

class Order
include Mongoid::Document
field :state, type: String, default: 'created'
end

次の例では、 fulfill_byフィールドに Proc のデフォルト値を指定します。

class Order
include Mongoid::Document
field :fulfill_by, type: Time, default: ->{ Time.now + 3.days }
end

注意

ドライバーは、クラスが を読み込むと、Proc インスタンスではないデフォルト値を評価します。ドライバーはドキュメントが インスタンス化される ときにProc 値を評価します。次のデフォルトのフィールド値では同等の結果は生成されません。

# Time.now is set to the time the class is loaded
field :submitted_at, type: Time, default: Time.now
# Time.now is set to the time the document is instantiated
field :submitted_at, type: Time, default: ->{ Time.now }

Procインスタンスで self キーワードを使用して、ドキュメントの状態に依存するデフォルト値を設定できます。 次の例では、 submitted_atフィールドの状態に依存するように fulfill_by のデフォルト値を設定します。

field :fulfill_by, type: Time, default: ->{
self.submitted_at + 4.hours
}

デフォルトでは 、Mongoid は他のすべての属性を設定して初期化した後に、Procのデフォルト値を適用します。 他の属性を設定する前にデフォルトを適用するには、次の例に示すように、pre_processed オプションを true に設定します。

field :fulfill_by, type: Time, default: ->{ Time.now + 3.days },
pre_processed: true

Tip

_idフィールドにデフォルトの Proc 値を設定するには、必ず pre-processed オプションを true に設定します。

アプリケーション内の元の名前でフィールドを参照しながら、データベースに保存する別のフィールド名を指定できます。 MongoDB はすべてのフィールド情報を各ドキュメントとともに保存するため、ストレージスペースを節約することができます。

as: キーワードを使用して、代替ストレージ名を設定できます。 次の例では、 nameというフィールドを作成し、Mongoid が n としてデータベースに保存します。

class Band
include Mongoid::Document
field :n, as: :name, type: String
end

Mongoid は nameフィールドを"n" として保存しますが、アプリケーションでは name としてフィールドにアクセスできます。

alias_attribute オプションを使用してフィールドのエイリアスを作成できます。 エイリアスを指定しても、Mongoid がデータベースにフィールドを保存する方法は変更されませんが、アプリケーション内の別の名前でフィールドにアクセスできるようになります。

次の例では、 nameフィールドのエイリアスを指定します。

class Band
include Mongoid::Document
field :name, type: String
alias_attribute :n, :name
end

フィールドエイリアスを削除するには、unalias_attribute オプションを使用できます。 次の例では、 nameフィールドの エイリアスを削除します。

class Band
unalias_attribute :n
end

また、unalias_attribute を使用して、事前定義された id エイリアスを _idフィールドから削除することもできます。 これを使用して、 _idフィールドと idフィールドに異なる値を保存できます。

デフォルトでは 、Mongoid ではモデルのフィールドを再定義できます。 フィールドが再定義されたときにエラーを発生させるには、mongoid.ymlファイルの duplicate_fields_exception 構成オプションを true に設定します。

duplicate_fields_exception オプションが true に設定されている場合でも、フィールド を定義するときに overwrite オプションを true に設定することで、特定のフィールドを再定義できます。 次の例ではnameフィールドを定義し、overwrite オプションを使用してそのフィールドを再定義します。

class Person
include Mongoid::Document
field :name
field :name, type: String, overwrite: true
end

デフォルトでは 、Mongoid はドキュメントの _idフィールドを定義し、Mongoid が自動的に生成する BSON::ObjectId 値を含めます。 モデルで指定することで、_idフィールドのタイプをカスタマイズしたり、デフォルト値を指定したりできます。

次の例では、カスタム _idフィールドを持つ Bandクラスを作成します。

class Band
include Mongoid::Document
field :name, type: String
field :_id, type: String, default: ->{ name }
end

_idフィールドのデフォルト値を省略できます。 フィールドにデフォルト値を指定しない場合、Mongoid は _id 値なしでドキュメントを永続化します。 最上位ドキュメントの場合、 MongoDBサーバーは自動的に _id 値を割り当てます。 ただし、埋め込みドキュメントの場合、サーバーは_id 値を割り当てません。

_idフィールドの値を指定しない場合、Mongoid はサーバーから自動的に割り当てられた値を取得しません。 このため、_id 値を使用してデータベースからドキュメントを取得することはできません。

指定されたフィールド型に変換できない値は、キャスト不可と見なされます。例、配列は Integerフィールドに割り当てられている場合、キャスト不可と見なされます。

v8.0 以降では、Mongoid は nil をキャスト不可の値に割り当てます。 元のキャストできない値は、フィールド名とともに attributes_before_type_cast ハッシュに保存されます。

フィールドと同じ名前のメソッドを指定し、read_attribute メソッドまたは write_attribute メソッドを呼び出して未加工の属性値で操作することで、フィールドのデフォルトの getter メソッドと setter メソッドを上書きできます。

次の例では、 Personクラスの nameフィールドのカスタム getter と setter を作成します。

class Person
include Mongoid::Document
field :name, type: String
# Custom getter for 'name' to return the name in uppercase
def name
read_attribute(:name).upcase if read_attribute(:name)
end
# Custom setter for 'name' to store the name in lowercase
def name=(value)
write_attribute(:name, value.downcase)
end
end

attr_readonly オプションを指定することで、読み取り専用のフィールドを指定できます。 これにより、 属性を持つドキュメントを作成できますが、更新はできません。

次の例では、 Bandクラスを作成し、nameフィールドを読み取り専用として指定しています。

class Band
include Mongoid::Document
field :name, type: String
field :origin, type: String
attr_readonly :name
end

一括更新メソッド(update_attributes など)を呼び出し、読み取り専用フィールドを渡すと、Mongoid は読み取り専用フィールドを無視し、他のすべてを更新します。 読み取り専用フィールド を明示的に更新しようとすると、Mongoid は ReadonlyAttribute 例外を発生させます。

注意

bitinc などのアトミック永続演算子を呼び出しても、読み取り専用フィールドへの変更は保持されます。

モデル全体を読み取り専用として指定する方法については、「 データ操作の実行 」ガイドの「 読み取り専用ドキュメント セクション」を参照してください。

Mongoid は、 i18 n gem を使用してローカライズされたフィールドをサポートしています。フィールドをローカル化すると、Mongoid はそのフィールドをロケールキーと値のハッシュとして保存します。 フィールドへのアクセスは、string 値と同じように動作します。 任意のフィールドタイプのフィールドをローカライズできます。

次の例では、ローカライズされた reviewフィールドを持つ Productクラスを作成します。

class Product
include Mongoid::Document
field :review, type: String, localize: true
end
I18n.default_locale = :en
product = Product.new
product.review = "Marvelous!"
I18n.locale = :de
product.review = "Fantastisch!"
product.attributes
# Outputs: { "review" => { "en" => "Marvelous!", "de" => "Fantastisch!" }

_translations メソッドを呼び出すと、一度にすべての翻訳を取得して設定できます。

product.review_translations
# Outputs: { "en" => "Marvelous!", "de" => "Fantastisch!" }
product.review_translations =
{ "en" => "Marvelous!", "de" => "Wunderbar!" }

i18 フォールバック機能を有効にすることで、ローカライズされたフィールドのフォールバックを指定できます。

Railsアプリケーションでフォールバックを有効にするには、環境で config.i18n.fallbacks 構成設定を設定し、フォールバック言語を設定します。

config.i18n.fallbacks = true
config.after_initialize do
I18n.fallbacks[:de] = [ :en, :es ]
end

モジュールを i18nバックエンドに含め、フォールバック言語を設定することで、非 Rails アプリケーションでフォールバックを有効にします。

require "i18n/backend/fallbacks"
I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
I18n.fallbacks[:de] = [ :en, :es ]

フォールバック を有効にした後、アクティブな言語に翻訳がない場合は、指定された フォールバック言語で検索されます。

フィールド を定義するときに fallbacks オプションを false に設定することで、指定されたフィールドのフォールバック言語を無効にすることができます。

class Product
include Mongoid::Document
field :review, type: String, localize: true, fallbacks: false
end

ローカライズされたフィールドをクエリする場合、Mongoid は現在のロケールと一致するようにクエリ条件を自動的に変更します。 次の例では、 enロケールでレビューを得るために Productクラスをクエリします。

# Match all products with Marvelous as the review. The current locale is :en.
Product.where(review: "Marvelous!")
# The resulting MongoDB query filter: { "review.en" : "Marvelous!" }

注意

ローカライズされたフィールドを広範にクエリする場合は、クエリを実行するロケールごとにインデックスを作成することをお勧めします。

戻る

フィールド型