Docs Menu
Docs Home
/ / /
Mongoid
/

CRUD 操作

項目一覧

  • ドキュメントの保存
  • 標準
  • アトミック
  • 再読み込み
  • 保存されていないドキュメントの再読み込み
  • フィールド値へのアクセス
  • ゲッターとセッター
  • カスタム ゲッターとセッター
  • read_attribute & write_attribute
  • ハッシュ アクセス
  • 一括属性書込み (write)
  • ダーティ トラッキング
  • 変更の表示
  • 変更をリセットする
  • 永続性
  • 以前の変更の表示
  • コンテナ フィールドの更新
  • 読み取り専用ドキュメント
  • [readConcern] の上書き readonly?

Mongoid は、アクティブ レコードやデータマッパーなどの他の Ruby マッパーに慣れるために、期待されるすべての CRUD 操作をサポートしています。 Mongoid と MongoDB の他のマッパーとの違いは、毎回ドキュメント全体をデータベースに書き込むのではなく、一般的な永続化操作が変更されたフィールドのみに対してアトミックな更新を実行することです。

永続性セクションでは、ドキュメント化された コマンドを実行するときに実行されるデータベース操作の例を示します。

Mongoid の標準永続メソッドは、他のマッピング フレームワークにある一般的なメソッドの形式になります。 次の表は、すべての標準操作を例とともに示しています。

操作

Model#attributes

ドキュメントの属性を string キーとその値を Mongoized 形式(db に保存する方法)で ``Hash`` として返します。

属性ハッシュには、すべての埋め込みドキュメントの属性とその埋め込みドキュメントなども含まれます。 埋め込み関連付けが空の場合、返されるハッシュにはそのキーは表示されません。

person = Person.new(first_name: "Heinrich", last_name: "Heine")
person.attributes
# => { "_id" => BSON::ObjectId('633467d03282a43784c2d56e'), "first_name" => "Heinrich", "last_name" => "Heine" }

Model.create!

検証またはサーバー エラーが発生した場合はエラーが発生します。

属性のハッシュを渡して、指定された属性を持つ単一のドキュメントを作成するか、ハッシュの配列を渡して複数のドキュメントを作成します。 ハッシュが 1 つ渡されると、対応するドキュメントが返されます。 ハッシュの配列が渡されると、ハッシュに対応するドキュメントの配列が返されます。

ブロックが に与えられた場合 create! の場合、そのドキュメントの保存を試みる前に、各ドキュメントを引数として順番に呼び出されます。

検証エラーやサーバーエラーなど、ドキュメントの保存に問題が発生した場合は、例外が発生し、ドキュメントは返されません。 ただし、ハッシュの配列が渡され、以前のドキュメントが正常に保存された場合、それらのドキュメントはデータベースに残ります。

Person.create!(
first_name: "Heinrich",
last_name: "Heine"
) # => Person instance
Person.create!([
{ first_name: "Heinrich", last_name: "Heine" },
{ first_name: "Willy", last_name: "Brandt" }
]) # => Array of two Person instances
Person.create!(first_name: "Heinrich") do |doc|
doc.last_name = "Heine"
end # => Person instance

Model.create

1 つまたは複数のドキュメントをインスタンス化し、検証に合格したらデータベースに挿入します。

create は に類似しています create! ただし、検証エラー時に例外は発生しません。 次のドキュメントを挿入しようとしたなど、サーバー エラーでは引き続きエラーが発生します: _id コレクション内に既に存在する。

検証エラーが発生した場合、それぞれのドキュメントは挿入されず、挿入されたドキュメントとともに返されます。 を使用する persisted? , new_record? or errors 返されたドキュメントのどのドキュメントがデータベースに挿入されたかを確認するメソッド。

Person.create(
first_name: "Heinrich",
last_name: "Heine"
) # => Person instance
Person.create([
{ first_name: "Heinrich", last_name: "Heine" },
{ first_name: "Willy", last_name: "Brandt" }
]) # => Array of two Person instances
Person.create(first_name: "Heinrich") do |doc|
doc.last_name = "Heine"
end # => Person instance
class Post
include Mongoid::Document
validates_uniqueness_of :title
end
posts = Post.create([{title: "test"}, {title: "test"}])
# => array of two Post instances
posts.map { |post| post.persisted? } # => [true, false]

Model#save!

変更された属性をデータベースに不可分的に保存し、新しい場合はドキュメントを挿入します。 検証に失敗した場合、またはサーバーエラーが発生した場合は例外が発生します。

変更された属性が保存されている場合は true を返し、そうでない場合は例外が発生します。

person = Person.new(
first_name: "Heinrich",
last_name: "Heine"
)
person.save!
person.first_name = "Christian Johan"
person.save!

Model#save

変更された属性をデータベースに不可分的に保存し、新しい場合はドキュメントを挿入します。

変更された属性が保存されている場合は true を返します。 検証エラーが発生した場合は false を返します。 ドキュメントが検証に合格したが保存中にサーバー エラーが発生した場合は、例外が発生します。

を渡す validate: false 検証をバイパスするオプション。

を渡す touch: false オプションを使用すると、 update_at フィールドへの更新を無視します。 保存されているドキュメントが以前に保存されていない場合、このオプションは無視され、 created_at フィールドと update_at フィールドは現在の時刻で更新されます。

person = Person.new(
first_name: "Heinrich",
last_name: "Heine"
)
person.save
person.save(validate: false)
person.save(touch: false)
person.first_name = "Christian Johan"
person.save

Model#update_attributes

データベース内のドキュメント属性を更新します。 検証に合格した場合は true を返し、合格していない場合は false を返します。

person.update_attributes(
first_name: "Jean",
last_name: "Zorg"
)

Model#update_attributes!

検証に失敗した場合は、データベース内のドキュメント属性を更新し、エラーが発生します。

person.update_attributes!(
first_name: "Leo",
last_name: "Tolstoy"
)

Model#update_attribute

検証をバイパスして、単一の属性を更新します。

person.update_attribute(:first_name, "Jean")

Model#upsert

ドキュメントに対して アップサート による MongoDB 置換を実行します。 ドキュメントがデータベースに存在し、 :replace オプションが true に設定されている場合は、アプリケーション内の現在のドキュメントが上書きされます(データベースには存在するが、アプリケーションのドキュメントインスタンスには存在しない属性はすべて失われます)。 の場合 :replace オプションが false(デフォルト)の場合、ドキュメントが更新され、アプリケーションのドキュメントにない属性は維持されます。 ドキュメントがデータベースに存在しない場合は、挿入されます。 これは次のみを実行することに注意してください。 {before|after|around}_upsert コールバック

person = Person.new(
first_name: "Heinrich",
last_name: "Heine"
)
person.upsert
person.upsert(replace: true)

Model#touch

ドキュメントの update_at タイムスタンプを更新し、オプションとして、提供された時間フィールドを 1 つ追加します。 これにより、すべてのノードへのアクセスが累積されます。 belongs_to オプションが設定されたドキュメントの 関連付け 。 この操作は検証とコールバックをスキップします。

破棄されたドキュメントにアクセスしようとすると、 FrozenErrorこれは破棄されたドキュメントの属性の更新を試みる場合と同じです。

person.touch
person.touch(:audited_at)

Model#delete

コールバックを実行せずにデータベースからドキュメントを削除します。

ドキュメントが永続化されていない場合、Mongoid は同じドキュメントをデータベースから削除しようとします。 _id.

person.delete
person = Person.create!(...)
unsaved_person = Person.new(id: person.id)
unsaved_person.delete
person.reload
# raises Mongoid::Errors::DocumentNotFound because the person was deleted

Model#destroy

破棄コールバックの実行中にデータベースからドキュメントを削除します。

ドキュメントが永続化されていない場合、Mongoid は同じドキュメントをデータベースから削除しようとします。 _id.

person.destroy
person = Person.create!(...)
unsaved_person = Person.new(id: person.id)
unsaved_person.destroy
person.reload
# raises Mongoid::Errors::DocumentNotFound because the person was deleted

Model.delete_all

コールバックを実行せずに、データベースからすべてのドキュメントを削除します。

Person.delete_all

Model.destroy_all

コールバックの実行中にデータベースからすべてのドキュメントを削除します。 これは、すべてのドキュメントをメモリに読み込むため、コストのかかる操作になる可能性があります。

Person.destroy_all

Mongoid は、次の永続性関連の属性を提供します。

属性

Model#new_record?

戻り値 true モデル インスタンスがまだデータベースに保存されていない場合。 の反対 persisted?

person = Person.new(
first_name: "Heinrich",
last_name: "Heine"
)
person.new_record? # => true
person.save!
person.new_record? # => false

Model#persisted?

戻り値 true モデル インスタンスが データベースに保存されている場合。 の反対 new_record?

person = Person.new(
first_name: "Heinrich",
last_name: "Heine"
)
person.persisted? # => false
person.save!
person.persisted? # => true

Mongoid は、Mongoid ドキュメントのメソッドとして MongoDB 更新演算子を公開します。 これらのメソッドが使用される場合、コールバックは呼び出されず、検証は実行されません。 サポートされている更新演算子は次のとおりです。

操作

Model#add_to_set

フィールドでアトミック $addToSet を実行します。

person.add_to_set(aliases: "Bond")

Model#bit

フィールドに対してアトミック $bit を実行します。

person.bit(age: { and: 10, or: 12 })

Model#inc

フィールドに対してアトミック $inc を実行します。

person.inc(age: 1)

Model#pop

フィールドでアトミック $pop を実行します。

person.pop(aliases: 1)

Model#pull

フィールドでアトミック $pull を実行します。

person.pull(aliases: "Bond")

Model#pull_all

フィールドに対してアトミック $pullAll を実行します。

person.pull_all(aliases: [ "Bond", "James" ])

Model#push

フィールドでアトミック $push を実行します。

person.push(aliases: ["007","008"])

Model#rename

フィールドでアトミックな $rename を実行します。

person.rename(bday: :dob)

Model#set

モデル インスタンスの属性を更新し、インスタンスがすでに永続化されている場合は、検証をバイパスしてフィールドに対してアトミック $set を実行します。

set は、 ハッシュ フィールドに値を深く設定することもできます。

set に値を深く設定することもできます embeds_one 関連付け。 このような関連付けのドキュメントが nil の場合、更新の前に 1 つのドキュメントが作成されます。

set はと一緒に使用しないでください has_one このような場合は、正しく機能しません。

person = Person.create!(name: "Ricky Bobby")
person.set(name: "Tyler Durden") # updates name in the database
person = Person.new
person.set(name: "Tyler Durden") # does not write to database
person.name # => "Tyler Durden"
person.persisted? # => true
class Post
include Mongoid::Document
field :metadata, type: Hash
end
post = Post.create!
post.set('metadata.published_at' => Time.now)
post.metadata['published_at'] # => Time instance
post.set('metadata.approved.today' => true)
post.metadata['approved'] # => {'today' => true}
class Flight
include Mongoid::Document
embeds_one :plan
end
class Plan
include Mongoid::Document
embedded_in :flight
field :route, type: String
end
flight = Flight.create!
flight.plan # => nil
flight.set('plan.route', 'test route')
flight.plan # => Plan instance
flight.plan.route # => "test route"

Model#unset

フィールドに対してアトミック $unset を実行します。

person.unset(:name)

これらのメソッドは検証をスキップするため、無効なドキュメントをデータベースに保存するだけでなく、アプリケーションに無効なドキュメントが存在する可能性があることに注意してください(その後、検証が失敗するため、 save呼び出しによる保存は失敗します)。

アトミック操作は、ドキュメントで#atomicallyメソッドを使用してグループ化できます。 All operations inside the block given to #atomically are sent to the cluster in a single atomic command. 例:

person.atomically do
person.inc(age: 1)
person.set(name: 'Jake')
end

#atomically ブロックはネストできます。 デフォルトの動作では、ブロックが終了するとすぐに各ブロックによって実行された変更が書込まれます。

person.atomically do
person.atomically do
person.inc(age: 1)
person.set(name: 'Jake')
end
raise 'An exception'
# name and age changes are still persisted
end

この動作は、 join_context: trueオプションを#atomicallyに指定するか、 join_contexts 構成オプションtrueに設定することでグローバルに変更できます。 When context joining is enabled, nested #atomically blocks are joined with the outer blocks, and only the outermost block (or the first block where join_contexts is false) actually writes changes to the cluster. 例:

person.atomically do
person.atomically(join_context: true) do
person.inc(age: 1)
person.set(name: 'Jake')
end
raise 'An exception'
# name and age changes are not persisted
end

コンテキスト結合動作は、Mongoid 構成でjoin_contextオプションを設定することで、デフォルトでグローバルに有効になります。 この場合、 #atomicallyブロックでjoin_context: falseを指定すると、独立した永続化コンテキストの動作を取得できます。

変更がクラスターにまだ保存されていない#atomicallyブロックで例外が発生した場合、Mongoid モデルで保留中の属性の変更はすべて元に戻されます。 例:

person = Person.new(name: 'Tom')
begin
person.atomically do
person.inc(age: 1)
person.set(name: 'Jake')
person.name # => 'Jake'
raise 'An exception'
end
rescue Exception
person.name # => 'Tom'
end

このセクションで説明されるアトミック操作は一度に 1 つのドキュメントに適用されるため、複数のドキュメントで呼び出される#atomicallyブロックをネストしても、異なるドキュメントへの変更は不可分的にまとめられます。 ただし、MongoDB は サーバー バージョン 4.0 以降、複数のドキュメント間でアトミックな永続性を提供するマルチドキュメントトランザクションを提供しています。

データベースからドキュメントの最新バージョンを取得するには、 reloadメソッドを使用します。 ドキュメントの属性に対する保存されていない変更はすべて失われます。

band = Band.create!(name: 'foo')
# => #<Band _id: 6206d06de1b8324561f179c9, name: "foo", description: nil, likes: nil>
band.name = 'bar'
band
# => #<Band _id: 6206d06de1b8324561f179c9, name: "bar", description: nil, likes: nil>
band.reload
# => #<Band _id: 6206d06de1b8324561f179c9, name: "foo", description: nil, likes: nil>

ドキュメントが再読み込みされると、その埋め込み関連付けもすべて同じクエリで再読み込みされます(埋め込みドキュメントはサーバー上の親ドキュメントに保存されているため)。 ドキュメントが関連付けを参照している場合、ロードされた関連付けの は再読み込みされず、値がクリアされ、次回のアクセス時にこれらの関連付けがデータベースから読み込まれるようになります。

注意

割り当てなどの関連付けに対する一部の操作では、新しいドキュメントが保持されます。 このような場合、再読み込みによって元に戻すことができない変更はありません。 次の例では、空の配列 の関連付けへの割り当てはすぐに永続され、再読み込みしてもドキュメントは変更されません。

# Assuming band has many tours, which could be referenced:
band = Band.create!(tours: [Tour.create!])
# ... or embedded:
band = Band.create!(tours: [Tour.new])
# This writes the empty tour list into the database.
band.tours = []
# There are no unsaved modifications in band at this point to be reverted.
band.reload
# Returns the empty array since this is what is in the database.
band.tours
# => []

モデルにシャードキーが定義されている場合、シャードキー値はリロード クエリに含まれます。

データベースに一致するドキュメントが含まれていない場合、Mongoid は通常Mongoid::Errors::DocumentNotFoundを発生させます。 ただし、構成オプションraise_not_found_errorfalseに設定されており、データベースに一致するドキュメントが含まれていない場合、Mongoid は現在のドキュメントを、属性がデフォルト値に設定されている新しく作成されたドキュメントに置き換えます。 重要な点は、次の例に示すように、これにより通常、ドキュメントの_idが変更されることです。

band = Band.create!
# => #<Band _id: 6206d00de1b8324561f179c7, name: "foo", description: nil, likes: nil>
Mongoid.raise_not_found_error = false
band.destroy
band.reload
# => #<Band _id: 6206d031e1b8324561f179c8, name: nil, description: nil, likes: nil>

このため、 raise_not_found_errorfalseに設定されている場合にreloadを使用することは推奨されません。

reload ドキュメントがまだ保存されていない場合に呼び出すことができます。 この場合、 reloadはドキュメントに指定されたid値(およびシャードキーが定義されている場合はシャードキー値)を使用してfindクエリを実行します。

existing = Band.create!(name: 'Photek')
# Unsaved document
band = Band.new(id: existing.id)
band.reload
band.name
# => "Photek"

Mongoid は、フィールド値にアクセスするいくつかの方法を提供します。

注意

以下で説明するすべてのアクセス メソッドでは、アクセス対象のフィールドがプロジェクションされると、のみに含まれていないため、またはなしで に含まれているためにMongoid::Errors::AttributeNotLoadedが発生します。 これは、読み取りと書込みの両方に適用されます。

推奨される方法は、宣言されたフィールドごとに生成された getter メソッドと setter メソッドを使用することです。

class Person
include Mongoid::Document
field :first_name
end
person = Person.new
person.first_name = "Artem"
person.first_name
# => "Artem"

このメカニズムを使用するには、各フィールドを明示的に宣言するか、モデル クラスで動的フィールドを有効にする必要があります。

getter メソッドと setter メソッドを明示的に定義して、値の変換や別のフィールド名での値の保存など、フィールドの読み取りや書き込みの際のカスタム動作を提供することができます。 この場合、 read_attributeメソッドとwrite_attributeメソッドを使用して値を直接読み取りと属性ハッシュに書込むことができます。

class Person
include Mongoid::Document
def first_name
read_attribute(:fn)
end
def first_name=(value)
write_attribute(:fn, value)
end
end
person = Person.new
person.first_name = "Artem"
person.first_name
# => "Artem"
person.attributes
# => {"_id"=>BSON::ObjectId('606477dc2c97a628cf47075b'), "fn"=>"Artem"}

注意

カスタム セッターはネストされた属性の割り当て中に呼び出されますが、関連付けが設定される前に呼び出されます。 このため、これらのメソッド中に関連付けが常に利用できない場合があるため、関連付けを参照するたびに関連付けを含めることをお勧めします。 コールバックは特定のイベントに対する操作の実行にも使用できます。関連付けはすでに設定されており、実行中に使用可能になります。

read_attributeメソッドとwrite_attributeメソッドは明示的に使用することもできます。 フィールドでストレージ フィールド名が指定されている場合、 read_attributewrite_attributeの両方で、宣言されたフィールド名または操作のストレージ フィールド名のいずれかを受け入れることに注意してください。

class Person
include Mongoid::Document
field :first_name, as: :fn
field :last_name, as: :ln
end
person = Person.new(first_name: "Artem")
# => #<Person _id: 60647a522c97a6292c195b4b, first_name(fn): "Artem", last_name(ln): nil>
person.read_attribute(:first_name)
# => "Artem"
person.read_attribute(:fn)
# => "Artem"
person.write_attribute(:last_name, "Pushkin")
person
# => #<Person _id: 60647a522c97a6292c195b4b, first_name(fn): "Artem", last_name(ln): "Pushkin">
person.write_attribute(:ln, "Medvedev")
person
# => #<Person _id: 60647a522c97a6292c195b4b, first_name(fn): "Artem", last_name(ln): "Medvedev">

read_attribute およびwrite_attributeでは使用済み名のフィールドを定義する必要はありませんが、 write_attributeを使用してフィールド値を書込むと、それぞれのフィールドは次のいずれかに定義されません。

person.write_attribute(:undefined, "Hello")
person
# => #<Person _id: 60647b212c97a6292c195b4c, first_name(fn): "Artem", last_name(ln): "Medvedev">
person.attributes
# => {"_id"=>BSON::ObjectId('60647b212c97a6292c195b4c'), "first_name"=>"Artem", "last_name"=>"Medvedev", "undefined"=>"Hello"}
person.read_attribute(:undefined)
# => "Hello"
person.undefined
# raises NoMethodError

read_attributeが欠落しているフィールドにアクセスするために使用されると、 nilが返されます。

Mongoid モデル[] []=Hashインスタンスは、属性への スタイルのアクセスを提供するために メソッドと メソッドを定義します。[]read_attributeのエイリアスであり、 []=write_attributeのエイリアスです。動作の詳細については、 read_attribute および write_attributeのセクションを参照してください。

class Person
include Mongoid::Document
field :first_name, as: :fn
field :last_name, as: :ln
end
person = Person.new(first_name: "Artem")
person["fn"]
# => "Artem"
person[:first_name]
# => "Artem"
person[:ln] = "Medvedev"
person
# => #<Person _id: 606483742c97a629bdde5cfc, first_name(fn): "Artem", last_name(ln): "Medvedev">
person["last_name"] = "Pushkin"
person
# => #<Person _id: 606483742c97a629bdde5cfc, first_name(fn): "Artem", last_name(ln): "Pushkin">

複数のフィールド値を一度に設定する場合でも、これを実現するさまざまな方法があります。

# Get the field values as a hash.
person.attributes
# Set the field values in the document.
Person.new(first_name: "Jean-Baptiste", middle_name: "Emmanuel")
person.attributes = { first_name: "Jean-Baptiste", middle_name: "Emmanuel" }
person.write_attributes(
first_name: "Jean-Baptiste",
middle_name: "Emmanuel",
)

Mongoid は、アクティブ モデルの API をミラーリングする API を使用して、変更されたフィールドまたは「ダーティ」フィールドの追跡をサポートします。 モデル内の定義されたフィールドが変更された場合、モデルはダーティとしてマークされ、追加の 動作が有効になります。

モデルの変更内容を確認するには、さまざまな方法があります。 変更は、ドキュメントがインスタンス化されてから、新しいドキュメントとして、またはデータベースからのロードによって保存されるまで記録されます。 永続化操作により、変更がクリアされます。

class Person
include Mongoid::Document
field :name, type: String
end
person = Person.first
person.name = "Alan Garner"
# Check to see if the document has changed.
person.changed? # true
# Get an array of the names of the changed fields.
person.changed # [ :name ]
# Get a hash of the old and changed values for each field.
person.changes # { "name" => [ "Alan Parsons", "Alan Garner" ] }
# Check if a specific field has changed.
person.name_changed? # true
# Get the changes for a specific field.
person.name_change # [ "Alan Parsons", "Alan Garner" ]
# Get the previous value for a field.
person.name_was # "Alan Parsons"

注意

ドキュメントにchanges changed_attributes関連付けを設定しても、 ハッシュまたは ハッシュは変更されません。これは、参照されているか埋め込まれているかにかかわらず、すべての関連付けに当てはまります。 参照された関連付けの _id(s) フィールドを変更すると、変更がchangeschanged_attributesハッシュに表示されることに注意してください。

リセット メソッドを呼び出すと、フィールドの変更をその前の値にリセットできます。

person = Person.first
person.name = "Alan Garner"
# Reset the changed name back to the original
person.reset_name!
person.name # "Alan Parsons"

Mongoid は、永続性操作の主要としてダーティ トラッキングを使用します。 保存のたびにドキュメント全体を書込む他のフレームワークとは異なり、ドキュメントの変更を検討し、変更された内容のみをアトミックに更新します。 変更が行われていない場合、Mongoid はModel#saveの呼び出しでデータベースにアクセスしません。

ドキュメントが永続化された後、 Model#previous_changesを呼び出すと、以前の変更内容を確認できます。

person = Person.first
person.name = "Alan Garner"
person.save # Clears out current changes.
# View the previous changes.
person.previous_changes # { "name" => [ "Alan Parsons", "Alan Garner" ] }

MONGOID-2951 まで注意してください が解決された場合、値をデータベースに永続化するには、コンテナ フィールドを含むすべてのフィールドを に割り当てる必要があります。

たとえば、次のようなセットに追加しても機能しません。

class Band
include Mongoid::Document
field :tours, type: Set
end
band = Band.new
band.tours
# => #<Set: {}>
band.tours << 'London'
# => #<Set: {"London"}>
band.tours
# => #<Set: {}>

代わりに、フィールド値はモデル外で変更され、次のようにモデルに戻される必要があります。

class Band
include Mongoid::Document
field :tours, type: Set
end
band = Band.new
tours = band.tours
# => #<Set: {}>
tours << 'London'
# => #<Set: {"London"}>
band.tours = tours
# => #<Set: {"London"}>
band.tours
# => #<Set: {"London"}>

ドキュメントを読み取り専用としてマークするには、 Mongoid.legacy_readonly機能フラグの値に応じて、次の 2 つの方法があります。

このフラグがオフの場合、そのドキュメントはドキュメントで#readonly!メソッドが呼び出されたときに読み取り専用としてマークされます。 このフラグがオフになっている読み取り専用ドキュメントでは、保存、更新、削除、破棄など、任意の永続化操作を実行しようとすると ReadonlyDocument エラーが発生します。 再読み込みしても読み取り専用状態はリセットされないことに注意してください。

band = Band.first
band.readonly? # => false
band.readonly!
band.readonly? # => true
band.name = "The Rolling Stones"
band.save # => raises ReadonlyDocument error
band.reload.readonly? # => true

このフラグをオンにすると、そのドキュメントがプロジェクションされた場合(つまり#onlyまたは#withoutを使用している場合)、ドキュメントは読み取り専用としてマークされます。 このフラグがオンになっている読み取り専用ドキュメントは、削除可能または破棄可能ではありません( ReadonlyDocumentエラーが発生します)が、保存と更新は可能になります。 読み取り専用ステータスは、ドキュメントを再読み込みするとリセットされます。

class Band
include Mongoid::Document
field :name, type: String
field :genre, type: String
end
band = Band.only(:name).first
band.readonly? # => true
band.destroy # => raises ReadonlyDocument error
band.reload.readonly? # => false

ドキュメントを読み取り専用にする別の方法は、読み取り専用を上書きすることです。 メソッド:

class Band
include Mongoid::Document
field :name, type: String
field :genre, type: String
def readonly?
true
end
end
band = Band.first
band.readonly? # => true
band.destroy # => raises ReadonlyDocument error

戻る

データの操作