获取对关联所有者对象的访问权限

时间:2011-07-15 22:44:26

标签: ruby-on-rails mongoid

我希望在elements模块中的以下代码中访问Processor关联的所有者。首先,调用Chapter.process

应用/模型/ chapter.rb

class Chapter
  include Mongoid::Document
  field :position, :type => Integer
  field :title, :type => String
  field :identifier, :type => String

  embedded_in :book
  embeds_many :elements

  def self.process!(git, file)
    chapter = new
    # Parsing of XML goes here, generating parsed_doc
    elements = parsed_doc.css("div.chapter > *")
    elements.each { |element| chapter.elements.process!(element) }
  end

然后传递给Processor内的代码,该代码实际上包含在Element类中,如下所示:

应用/模型/ element.rb

class Element
  include Mongoid::Document
  extend Processor
  field :tag, :type => String
  field :identifier, :type => String
  field :title, :type => String

  embedded_in :chapter
end

Processor类的定义如下:

module Processor

  def process!(markup)
    [ASSOCIATION OWNER GOES HERE].elements.send("process_#{markup.name}!", markup)
  end

我需要这个的原因是因为我试图单独调用send,但是Monogid坚持认为:

  

不允许访问Element的集合,因为它是嵌入式文档,请从根文档访问集合。

所以看起来这样做的唯一方法就是访问此关联的父对象。我知道文档实例应该有一个_parent方法,但在这种情况下,这个方法是在集合上调用的,而不是实例。

那么如何从这个process!方法中引用关联对象?

2 个答案:

答案 0 :(得分:1)

这里的问题是您正在扩展模块,因此self将引用类而不是元素实例。如果您更改要包含在Element中的模块或通过任何其他方式使方法process!成为实例方法,则可以执行self.chapter.elements

如果元素可以嵌入到除章节self._parent.elements之外的其他模型中,那么它将是一个更好的选择,但我不会推荐它,因为它没有记录,并且可能会在将来版本的mongoid中更改,恕不另行通知。

答案 1 :(得分:1)

使用Mongoid,在创建父对象之前,不能按照建议的方式执行此操作,因为当您调用self.process!时,章节尚未保留,您没有“根文档”。根据你的约束,让这个工作的唯一方法就是调用self.process!一旦创建了章节对象,就从after_create过滤器开始。