【问题标题】:Mongoid embedded document parent not set in after_initialize callback未在 after_initialize 回调中设置 Mongoid 嵌入文档父级
【发布时间】:2011-08-26 14:53:14
【问题描述】:

我正在尝试从 after_initialize 回调中引用嵌入文档的父对象。

这是我的设置模型:

require 'mongo'
require 'mongoid'

connection = Mongo::Connection.new
Mongoid.database = connection.db('playground')

class Person
  include Mongoid::Document

  embeds_many :posts
end

class Post
  include Mongoid::Document

  after_initialize :callback_one

  embedded_in :person, :inverse_of => :post

  def callback_one
    puts "in callback"
    p self.person
  end
end

这会导致我不想要的行为:

a = Person.new
a.posts.build
puts "after callback"
p a.posts.first.person

吐出来:

[d][Moe:~]$ ruby test.rb 
in callback
nil
after callback
#<Person _id: 4e57b0ecba81fe9527000001, _type: nil>

要获得所需的行为,我可以手动执行此操作:

b = Person.new
c = Post.new(person: b)
puts "after callback"
p c.person

这给了我:

d][Moe:~]$ ruby test.rb 
in callback
#<Person _id: 4e57b386ba81fe9593000001, _type: nil>
after callback
#<Person _id: 4e57b386ba81fe9593000001, _type: nil>

唯一的问题是它在从数据库加载对象时不起作用,在这种情况下,人们会认为 person 已经被设置,因为它是从人那里加载的,但它是不是。

有谁知道这是否是期望的行为,如果是,你能告诉我为什么吗? 如果这不是所需的行为,谁能告诉我一个解决方法?

【问题讨论】:

  • 这个问题在 Mongoid 3 中似乎也存在。

标签: mongoid


【解决方案1】:

这个问题在 GitHub 上有几个问题:#613、#815 和 #900。

Mongoid v2.2.0 昨天已经发布,但仍然没有包含来自#900 的补丁。所以没有简单的方法可以做到这一点。

根据您的用例,延迟加载可能已经足够了:

class Post
  include Mongoid::Document

  embedded_in :person, :inverse_of => :post

  # This won't work yet.
  #
  # after_build :init
  #
  # def init
  #  @xyz = person.xyz
  # end

  def xyz
    @xyz ||= person.xyz
  end

  def do_something
    xyz.do_some_magic
  end
end

【讨论】:

  • 感谢您的解决方法,我还没有尝试过延迟加载,我想我会等待#900。
猜你喜欢
  • 2011-05-22
  • 2016-02-11
  • 1970-01-01
  • 2013-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-19
相关资源
最近更新 更多