Mongoid embeds_many:推送文档而不保存以保留脏状态

问题描述:

在Mongoid中,将文档推入embeds_many关系会自动将文档保留到数据库中。通常情况下,这很好,但当我需要跟踪对嵌入式文档的更改时遇到问题。Mongoid embeds_many:推送文档而不保存以保留脏状态

假设你有两种型号:

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文档,然后而不立即将它保持它(通过<<push)添加到list

我知道,Mongoid确实提供了一个选项来设置embeds_many关系没有持续性(见http://mongoid.org/en/mongoid/docs/relations.html#embeds_many):

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

的问题存在着Mongoid为您创建项目实例。在我的情况下,embeds_many关系中的文档可能是项目的子类(例如SpecialItem < Item),这对于build不起作用。但如果有人知道解决这个限制的方法,我也很乐意接受它作为答案。

要跟进“建设一个子类”问题,使用例如,您可以:

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

要指定要Mongoid打造适合你的(子)类。

回答我自己的问题:通过将父文档分配给子代来解决问题,而不是将子代添加到列表或子代。

继续在上面的例子中,你应该做的

item.list = list #no database query 

代替

list.items << item #automatic database insert 

设置父 - 没有自动保存任何东西到数据库孩子参考。