2011-11-12 7 views
0

でのActiveRecordのミューテーターにアクセスすることはできません: これは「無記号なしのメソッドフィールド1」というエラーを与える:は、私はRailsのコントローラ内と私はブロック内の私のインスタンス変数にアクセスしようとしていますブロック

Prawn::Document.generate("hello.pdf") do 
    @model.field1 
end 

私はこれを行う場合は、それが動作します:

my_model = @model 
Prawn::Document.generate("hello.pdf") do 
    my_model.field1 
end 

これはブロック内でのActiveRecordのアクセサまたはインスタンス変数とは何かを持ってもらえますか?

+0

この質問はあなたにも答える必要があります:http://stackoverflow.com/questions/5150483/instance-variable-not-available-inside -a-ruby-block – topek

+0

ありがとう、私はこのスレッドは良い答えがあると思う:PIは、これらの2つのスレッドを1つにマージする意味がないと思う。 – m33lky

答えて

1

ブロック内のコードがPrawn :: Documentオブジェクトのコンテキストで実行されるため、このようなことが起こります。のは、このコードの中に行こう:

module Prawn 
    class Document 
    def self.generate(filename,options={},&block) 
     pdf = new(options,&block) 
     pdf.render_file(filename) 
    end 

    def initialize(options={},&block) 
     if block 
     block.arity < 1 ? instance_eval(&block) : block[self] 
     end 
    end 
    end 
end 

あなたが見ることができるように、blockselfとしてDocumentオブジェクトで実行されます。それはselfのインスタンス変数として@modelを見つけようとしますが、これを行うことはできず、nilを返します。ローカル変数modelを使用すると、クロージャのヘルプが表示され、コードが正常に動作しています。

+0

また、 'my_model = @ model'で行ったように、インスタンス変数をRubyの変数に変換する方法はありますか? – m33lky

3

この種の問題は、ブロックが別のコンテキストで実行されているときに表示されます。通常はinstance_evalです。それでは、コードをチェックしてみましょう:

#lib/prawn/document.rb: Document#initialize  
if block 
    block.arity < 1 ? instance_eval(&block) : block[self] 
end 

あり、あなたのinstance_evalを持って、あなたはまた、溶液を見ることができます:引数として文書を受け入れブロックを渡すと、あなたは今、いつものようにインスタンス変数にアクセスできるようになります: