我在Rails控制器中,我正在尝试访问块中的实例变量: 这给出了一个错误,说“没有方法字段1为Nil”:
Prawn::Document.generate("hello.pdf") do
@model.field1
end
但是,如果我这样做,那么它可行:
my_model = @model
Prawn::Document.generate("hello.pdf") do
my_model.field1
end
这是否与块中的ActiveRecord访问器或实例变量有关?
答案 0 :(得分:3)
当块在不同的上下文中执行时,通常通过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 :(得分: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
如您所见,block
与Document
对象一起执行为self
。它试图找到@model作为self
的实例变量,不能这样做并返回nil
。如果您使用局部变量model
,您将获得闭包的帮助,并且您的代码正常运行