Way*_* Ye 5 yaml ruby-on-rails delayed-job
在application_controller的一个动作中,如果我们尝试:
p request.env.to_yaml
Run Code Online (Sandbox Code Playgroud)
我会收到这个错误:
TypeError: can't dump anonymous module: #<Module:0x007fee26e34ad8>
from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:267:in `visit_Module'
from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:102:in `accept'
from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:447:in `block in dump_ivars'
from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:445:in `each'
from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:445:in `dump_ivars'
from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:124:in `visit_Object'
from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:102:in `accept'
from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:447:in `block in dump_ivars'
from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:445:in `each'
from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:445:in `dump_ivars'
from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:124:in `visit_Object'
from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:102:in `accept'
from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:292:in `block in visit_Hash'
from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:290:in `each'
from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:290:in `visit_Hash'
from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:102:in `accept'
Run Code Online (Sandbox Code Playgroud)
我的问题是:如何序列化为request.envyaml?
实际上,我应该将request.env传递给delayed_job并发送电子邮件,我收到此错误,因为delayed_job需要将对象序列化为DB.
问题是,request.env哈希有很多嵌套对象(尤其是模块),无法转换为yaml.诀窍是删除无法转换的哈希部分.
tmp_env = request.env.clone
tmp_env.delete "action_dispatch.routes"
tmp_env.delete "action_controller.instance"
tmp_env["action_dispatch.remote_ip"] = tmp_env["action_dispatch.remote_ip"].to_s
p tmp_env.to_yaml # now it works
Run Code Online (Sandbox Code Playgroud)
我们首先克隆原始env哈希,以免意外修改它.然后我们从我们的副本中删除这些键,这会导致错误.
tmp_env["action_dispatch.routes"]包含ActionDispatch::Routing::RouteSet对象中未命名模块的引用,这是导致错误的原因.我们最好删除它.
tmp_env["action_controller.instance"]包含对原始env-hash 的引用(我们无法转换).删除它.
最后tmp_env["action_dispatch.remote_ip"]看起来像一个字符串(在检查它时),但它是一个ActionDispatch::RemoteIp::GetIp实例.它包含对原始env哈希的另一个引用.我们将其转换为字符串,因为我不知道您以后是否对该密钥感兴趣.
此外,您可以删除更多的键来减少您的yaml输出的大小.但是,这应该可以工作而不会抛出您遇到的错误.更精简的解决方案是从空哈希开始,只复制您在yaml输出中真正需要的键.
用ruby 1.9.3和rails 3.2.13测试
根据来自Physic的代码,可能听起来有点奇怪,但是
request.env.instance_eval "def name; 'some_name'; end"
Run Code Online (Sandbox Code Playgroud)
可能会起作用。酷吧,嗯?
| 归档时间: |
|
| 查看次数: |
3232 次 |
| 最近记录: |