我有一个Rails 4.2应用程序,文件上传流量很大。
我想覆盖rack.multipart.tempfile_factory
,以便在接受文件上传时提供与Rack创建的临时文件相关的其他行为。
那么我在哪里以及如何更改Rack的env
哈希完全?尝试在初始化程序中执行env['...'] = ...
,env
未定义。将其更改为ENV
会引发错误,说它无法将lambda转换为String(rack.multipart.tempfile_factory
需要lambda,因此我不能将其更改为String)。在控制器方法中使用request.env
无效。我通过复制粘贴库存工厂的一行代码测试了最后一个,并添加了一个随机数写入一个固定路径的文件;上传几个文件后,该文件从未在第一时间创建,所以你去了。
我正在寻找一个官方的解决方案,并没有打算猴子修补Rack。它的规格说明这是可能的,那我该怎么做呢?
当然,如果一切都失败了,我会诉诸黑客,但我更愿意先听听官方的做法。
(虽然我们在此,您是否还可以推荐使用无宝石解决方案覆盖rack.hijack_io
,并提供一些真实示例?特别是搜索该内容并不是很有帮助,没有人似乎提供了端到端的工作解决方案,只有点和点。
感谢您的考虑。
答案 0 :(得分:2)
env
您只需要覆盖Application#call
。在config/application.rb
(或config/environments/production.rb
,如果您愿意),您可以添加以下方法:
class Application < Rails::Application
...
def call(env)
env["rack.multipart.tempfile_factory"] = ->(what, now) { "lambda time" }
super(env)
end
...
end
有关详情,请参阅#call。
ENV
ENV
是Ruby中的常量,对应于shell环境。这允许您在shell脚本中执行以下操作:
$ export MY_VAR=hahahaha
...
irb> ENV['MY_VAR'] #=> "hahahaha"
它不仅仅是一个Rack变量 - 它是一个Ruby常量!
您的错误&#34;无法将lambda转换为字符串&#34;是因为所有ENV
值必须是字符串。所以,即使你做了
$ export MY_VAR=42
你会得到
irb> ENV['MY_VAR'] #=> "42"
其中"42"
是字符串,而不是整数。