我正在使用Prawn gem写入PDF。我已经开始编写PDF的操作,但我不明白如何以正确的方式使用我的数据。我有:
def download
@bid = Bid.find(params[:bid_id])
@title = @bid.bid_title.gsub(/\s+/, "")
Prawn::Document.generate("#{@title}.pdf") do
text @bid.client_name
end
end
在我添加文字的地方,出价为零。如何在下面的块中使用我之前创建的@bid
?
答案 0 :(得分:1)
挖掘源代码以了解所有魔法的工作方式通常很有用。
如果我们考虑Prawn source code,我们可以看到方法self.generate(filename, options = {}, &block)
中的块被传输到Prawn :: Document.new方法。因此,我们将考虑Prawn :: Document initialize
方法。在那里我们可以看到以下代码:
if block
block.arity < 1 ? instance_eval(&block) : block[self]
end
#arity is a number of block arguments.
# block[self] is a block.call(self)
如果我们简化Prawn源代码,我们可以模拟这种情况以便更好地理解它:
module Prawn
class Document
def self.generate(filename, &block)
block.arity < 1 ? instance_eval(&block) : block[self]
end
end
end
class A
def initialize
@a = 1
end
def foo
qwe = 1
Prawn::Document.generate("foobar") do
p @a
p qwe
p instance_variables
end
end
end
A.new.foo
# Output:
nil # @a
1 # qwe
[] # there is no instance_variables
但是如果我们为块提供一个参数,那么将调用generate中的另一个条件(block [self]而不是instance_eval):
module Prawn
class Document
def self.generate(filename, &block)
block.arity < 1 ? instance_eval(&block) : block[self]
end
end
end
class A
def initialize
@a = 1
end
def foo
qwe = 1
Prawn::Document.generate("foobar") do |whatever|
p @a
p qwe
p instance_variables
end
end
end
A.new.foo
# Output
1 # @a
1 # qwe
[:@a] # instance_variables
所以在你的情况下,我认为这段代码会起作用:
def download
@bid = Bid.find(params[:bid_id])
@title = @bid.bid_title.gsub(/\s+/, "")
Prawn::Document.generate("#{@title}.pdf") do |ignored|
text @bid.client_name
end
end
或
def download
bid = Bid.find(params[:bid_id])
title = @bid.bid_title.gsub(/\s+/, "")
Prawn::Document.generate("#{title}.pdf") do
text bid.client_name
end
end
答案 1 :(得分:1)
您的问题是Prawn::Document.generate
在Prawn :: Document实例的上下文中评估块。这意味着块中的实例变量将被解析为Prawn :: Document对象的实例变量,因为在块的上下文中它是self
。
要使其工作,请使用局部变量代替(或除了)实例变量。