2011-07-15 16 views
1

Processorモジュール内の次のコードで、elementsアソシエーションのオーナーにアクセスする予定です。まずアップ、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 

これは、実際にこのようなElementクラスに含まれているProcessor内部コードにオフに渡します

アプリ/モデル/ 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 
クラスは次のように定義されている

module Processor 

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

私はこれを必要とする理由は、私は単にそれ自体でsendを呼び出すことを試みてきたが、Monogidは主張しているので、その:

のためのコレクションへのアクセス要素は埋め込みドキュメントであるため許可されていません。ルートドキュメントからコレクションにアクセスしてください。

これを行う唯一の方法は、この関連付けの親オブジェクトにアクセスすることだと思われます。ドキュメントのインスタンスに_parentメソッドがあるはずですが、この場合、このメソッドはコレクションで呼び出されていますが、インスタンスではありません。

このprocess!メソッド内から関連オブジェクトを参照するにはどうすればよいですか?

+0

わかっているのか分かりませんが、 'chapter'から' chapter.elements.process!(element、chapter) 'を直接渡すとどうなりますか? – fl00r

+0

@ fl00r:Elementの 'create!'メソッドは何のために作成されているのか何とか知っていなければなりません。 –

答えて

1

ここでの問題はモジュールを拡張しているためです。selfは要素インスタンスの代わりにクラスを参照します。 Elementに含めるモジュールを変更したり、他の手段でメソッドprocess!をインスタンスメソッドにする場合は、self.chapter.elementsを実行できます。

self._parent.elements以外のモデルに要素を埋め込むことができますが、これは文書化されておらず、将来のバージョンのmongoidでは予告なしに変更される可能性があるため、推奨しません。

+0

ありがとう、私はfl00rの提案を使用してこれを回避しました。あなたのが最も近いです。 –

1

Mongoidでは、親オブジェクトの作成後、self.process!を呼び出したときに章がまだ保持されていないので、あなたは "ルートドキュメント"がありません。あなたの制約を受けてこれを動作させる唯一の方法は、self.processを呼び出すことです!チャプターオブジェクトが作成されるとafter_createフィルターから削除されます。

関連する問題