【问题标题】:Mongoid embeds_many: push document without save in order to preserve dirty stateMongoid embeds_many:推送文档而不保存以保持脏状态
【发布时间】:2013-03-20 11:02:07
【问题描述】:

在 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 文档,然后将其添加到list(通过&lt;&lt;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 &lt; Item),它不适用于build。但是,如果有人知道解决此限制的方法,我也很乐意接受它作为答案。

【问题讨论】:

    标签: mongoid


    【解决方案1】:

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

    继续上面的例子,你应该这样做

    item.list = list  #no database query
    

    而不是

    list.items << item  #automatic database insert
    

    设置父子引用而不自动将任何内容保存到数据库中。

    【讨论】:

      【解决方案2】:

      要使用您的示例跟进“构建子类”问题,您可以:

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

      指定您希望 Mongoid 为您构建的(子)类。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-10
        • 1970-01-01
        • 2012-01-16
        • 1970-01-01
        相关资源
        最近更新 更多