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