2009-06-15 5 views
1

に混入モジュールの初期化I持っているこの:モデル

class Bullet < ActiveRecord::Base 
    include StagedVersionMethods 
    ... 
end 

そしてこの

module StagedVersionMethods  
    def initialize 
    puts self.bullet_id 
    end 
end 

私は弾丸のインスタンスを作成すると、モジュールは、メソッドの火災を初期化しますが、私はActiveRecordの取得エラー: ... activerecord-2.2.2/lib/active_record/attribute_methods.rb:268: `read_attribute '

私は、プリマが必要なインスタンス変数を初期化しようとしています私がミキシングしているレコードのキー値。モジュール内の他のメソッドは、このインスタンス変数で動作します。

self(そのコンテキストではARレコードではないため)コールバックは、タスクにも適合しません。

これにどのようにアプローチする必要がありますか?あなたのような初期化を定義する場合

おかげ

答えて

0

は:

def initialize(*atts) 
    super(*atts) 
    puts self.bullet_id 
end 

その後、私はそれはあなたが最初のActiveRecordの初期化を使用するためのオブジェクトを正しく設定しますと、それはあなたがやりたいと思います。しかし、私はあなたが達成しようとしているものに対するアプローチがどれほど頑強であるかはわかりません。オブジェクトが初期化されるのではなく、アクセスされたときにこのインスタンス変数を作成する方が適切かもしれません。

インスタンス変数に何をしたいのかわからないと難しいです。

+0

おかげShadwell、 インスタンス変数を、この動作を混在させることができます。それは "親"の箇条書きの一時的なコピーを表し、モジュールはメソッド内でhas_temp_version ?, apply_temp_version、discard_temp_versionなどのメソッドをMOdelに組み込みます。 私はあなたが示唆したアプローチを試してみましたが(これは完璧な意味を持っています)、bullet_idを含む自己の属性はすべてゼロです。 私はあなたの2番目の提案を現在使用しています。それはうまくいきます。私が気に入っていたよりも配管が少しだけあります。 乾杯。 – Paul

4

ActiveRecordのイニシャライザをオーバーライドすると、デバッグが困難になるという奇妙な副作用が発生する可能性があるため、お勧めしません。推奨されるアプローチは、ActiveRecordが代わりに提供する:after_initializeコールバックを使用することです。あなたはまだそれに行われた編集で、例えば「自己」のコピーになります...モジュールを介してで

module MyCleverMixin 

    def after_initialize 
    puts "I'm Initializing!" 
    end 

end 


class MyModel < ActiveRecord 

    include MyCleverMixin 

end 
+0

ありがとうございました。問題は、私がモジュールを混合しているモデルであることをクラスが期待していましたが、クラスのクラスは「クラス」であり、ブロックは決して呼び出されません。私は棒の間違った終わりを得ていますか? ありがとうございます。 – Paul

+0

実際、mixinでafter_initializeを定義するだけでこれを単純化することができます。上記の私の編集したコードを見てください。 – user123226

+0

これは 'include MyCleverMixin'ですか? データベースから既存の箇条書きを見つけたときに、after_initializeコールバックが呼び出されないことに注意してください。 after_findも定義する必要があります。 – Shadwell