Mongoid встроенный родительский документ не установлен в обратном вызове after_initialize - PullRequest
2 голосов
/ 26 августа 2011

Я пытаюсь сослаться на родительский объект внедренного документа из обратного вызова 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 уже будет установлен, потому что он загружается от пользователя, но не.

Кто-нибудь знает, является ли это желаемым поведением, и если это так, можете ли вы сказать мне, почему? Если это не желаемое поведение, может кто-нибудь сказать мне обходной путь?

1 Ответ

1 голос
/ 29 августа 2011

Существует несколько проблем для этой проблемы на 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
...