【问题标题】:Updating embedded document with Mongoid updates the parent document instead使用 Mongoid 更新嵌入文档会更新父文档
【发布时间】:2012-05-14 19:01:54
【问题描述】:

当我尝试更新嵌入文档 (embeds_many) 上的属性时,mongoid 无法保存更改,并且奇怪地将更改的属性添加为父文档上的新属性。这是一个简单的单元测试,说明了我正在尝试做的事情:

class Tab
  include Mongoid::Document
  field :name, :type => String
  embeds_many :components, :class_name => 'TabComponent'
end

class TabComponent
  include Mongoid::Document
  embeds_many :components, :class_name => "TabComponent"
end

class TabColumn < TabComponent
  field :width, :type => Integer
end

require 'test_helper'

class TabTest < ActiveSupport::TestCase
  test "create new tab" do
    tab = Tab.new({
      :name => "My Demo Tab",
      :components => [TabColumn.new({
        :width => 200
      })]
    })

    tab.save!

    tab.components[0].width = 300
    tab.save!

    assert_equal tab.components[0].width, 300 # passes
    tab.reload
    assert_equal tab.components[0].width, 300 # fails!
  end
end

这是日志输出:

MONGODB (39ms) beam_test['system.namespaces'].find({})
MONGODB (27ms) beam_test['$cmd'].find({"count"=>"tabs", "query"=>{}, "fields"=>nil}).limit(-1)
MONGODB (38ms) beam_test['tabs'].find({})
MONGODB (0ms) beam_test['tabs'].remove({:_id=>BSON::ObjectId('4fb153c4c7597fbdac000002')})
MONGODB (0ms) beam_test['tabs'].insert([{"_id"=>BSON::ObjectId('4fb15404c7597fccb4000002'), "name"=>"My Demo Tab", "components"=>[{"_id"=>BSON::ObjectId('4fb15404c7597fccb4000001'), "_type"=>"TabColumn", "width"=>200}]}])
MONGODB (0ms) beam_test['tabs'].update({"_id"=>BSON::ObjectId('4fb15404c7597fccb4000002')}, {"$set"=>{"width"=>300}})
MONGODB (27ms) beam_test['tabs'].find({:_id=>BSON::ObjectId('4fb15404c7597fccb4000002')}).limit(-1)

我做错了吗?请注意,我认为问题不是多态性,如果我通过在 TabComponent 上添加宽度来简化事情,则会观察到相同的行为。

【问题讨论】:

  • 这是一个完全合理的问题 - 不知道为什么你被否决了。

标签: ruby-on-rails mongodb mongoid


【解决方案1】:

您的关系中有一个简单的错误,请改用以下方法来完成您的 embeds_many / Embedded-in 关系的对称性。

class TabComponent
  include Mongoid::Document
  embedded_in :tab
end

在上面的日志输出中,您会看到:

MONGODB (0ms) beam_test['tabs'].update({"_id"=>BSON::ObjectId('4fb15404c7597fccb4000002')}, {"$set"=>{"width"=>300}})

经过上述修复后,我现在得到:

MONGODB (0ms) free11819_mongoid_embedded_update_test['tabs'].update({"_id"=>BSON::ObjectId('4fb270fee4d30bbc20000002')}, {"$set"=>{"components.0.width"=>300}})

注意widthcomponents.0.width 的区别。

希望这有助于您顺利上路。

【讨论】:

  • 非常感谢!这完全解决了我的问题。我从来没有想过我必须以两种方式定义关联。
  • 你也拯救了我的一天! :D
  • 非常感谢。不知何故错过了我的一个模型:(
猜你喜欢
  • 2014-03-20
  • 1970-01-01
  • 1970-01-01
  • 2014-06-12
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多