не может получить доступ к мутаторам ActiveRecord в блоке - PullRequest
0 голосов
/ 13 ноября 2011

Я нахожусь внутри контроллера Rails и пытаюсь получить доступ к моей переменной экземпляра в блоке: Это приводит к ошибке, говорящей, что «нет метода field1 для Nil»:

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

Однако, если я сделаю это, то это сработает:

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

Может ли это быть как-то связано с аксессорами ActiveRecord или переменными экземпляра в блоке?

Ответы [ 2 ]

3 голосов
/ 13 ноября 2011

Эта проблема возникает, когда блок выполняется в другом контексте, обычно через instance_eval.Итак, давайте проверим код:

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

Там у вас есть instance_eval, и вы также можете увидеть решение: передайте блок, который принимает документ в качестве аргумента, и вы теперь сможете получить доступ кпеременные экземпляра как обычно:

Prawn::Document.generate("hello.pdf") do |doc|
  @my_model.field1
end
1 голос
/ 13 ноября 2011

Это происходит потому, что код внутри блока выполняется в контексте объекта 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

Как видите, block выполняется с Document объектом как self.Он пытается найти @model в качестве переменной экземпляра self, не может этого сделать и возвращает nil.Если вы используете локальную переменную model, вы получите помощь замыканий, и ваш код работает правильно

...