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
设置父 - 没有自动保存任何东西到数据库孩子参考。