6

Mongoid では、ドキュメントをリレーションにプッシュするembeds_manyと、ドキュメントがデータベースに自動的に永続化されます。通常はこれで問題ありませんが、埋め込まれたドキュメントの変更を追跡する必要がある場合に問題が発生します。

2 つのモデルがあるとします。

class List
  include Mongoid::Document
  embeds_many :items
  field :title
end

class Item
  include Mongoid::Document
  embedded_in :list
  field :name
end

これは .changes 属性で起こります:

list = List.new(title: 'List title')
list.save  #list is now persisted
item = Item.new(name: 'Item name')
item.changes  #returns Hash with {'name' => [nil, 'Item name']}
list.items << item  #saves item to database under the hood
item.changes  #returns empty Hash, because item was autosaved with list

アイテムをリストにプッシュする前に行われた変更を検査するために使用できますitem.previous_changesが、私の特定のケースでは、これにより物事を管理しやすくするためのあらゆる種類の問題が発生します。

私が達成したいのは、Itemドキュメントを初期化してから、すぐに永続化せずに(またはlistを介し​​て)追加できるようにすることです。<<push

私は、Mongoid がembeds_many永続化せずにリレーションをセットアップするオプションを提供していることを認識しています ( http://mongoid.org/en/mongoid/docs/relations.html#embeds_manyを参照):

list.items.build(name: 'Another item')

問題は、Mongoid が Item インスタンスを作成することです。私の場合、embeds_manyリレーション内のドキュメントは Item のサブクラス (例: SpecialItem < Item) である可能性があり、これは ではうまく機能しませんbuild。しかし、誰かがこの制限を回避する方法を知っていれば、それを答えとして喜んで受け入れます.

4

2 に答える 2

5

私自身の質問に答えるには、問題は、子を子のリストに追加するのではなく、親ドキュメントを子に割り当てることで解決されます。

上記の例を続けると、次のことを行う必要があります

item.list = list  #no database query

それ以外の

list.items << item  #automatic database insert

データベースに何も自動保存せずに親子参照を設定します。

于 2013-03-21T11:36:41.460 に答える
2

あなたの例を使用して「サブクラスの構築」の問題をフォローアップするには、次のことができます。

list.items.build({
  name: "Another Item"
}, SpecialItem)

Mongoid にビルドしてもらいたい (サブ) クラスを指定します。

于 2013-11-06T03:30:55.157 に答える