如何重现/清理凌乱的POST参数以避免使用delayed_job的YAML序列化问题?
今天,每次我开始使用delayed_job
工作者时,这个过程都会立刻死去。
经过一些调查(并找出有关delayed_job
的前台模式),我终于发现问题是delayed_job
序列化我的活动记录对象的方式是在YAML加载部分触发exception:
Psych::SyntaxError: (): mapping keys are not allowed in this context at line 7 column 14 from /Users/mick/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/1.9.1/psych.rb:203:in `parse' from /Users/mick/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/1.9.1/psych.rb:203:in `parse_stream' from /Users/mick/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/1.9.1/psych.rb:151:in `parse' from /Users/mick/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/1.9.1/psych.rb:127:in `load' from /Users/mick/.rvm/gems/ruby-1.9.3-p448/gems/safe_yaml-0.9.7/lib/safe_yaml.rb:144:in `load_with_options' from (irb):111 from /Users/mick/.rvm/gems/ruby-1.9.3-p448/gems/railties-3.2.16/lib/rails/commands/console.rb:47:in `start' from /Users/mick/.rvm/gems/ruby-1.9.3-p448/gems/railties-3.2.16/lib/rails/commands/console.rb:8:in `start' from /Users/mick/.rvm/gems/ruby-1.9.3-p448/gems/railties-3.2.16/lib/rails/commands.rb:41:in `' from script/rails:6:in `require' from script/rails:6:in `'
在delayed_job
尝试时发生了这种情况:
YAML.load(my_job.handler)
( 其他人在我面前有同样的问题 )
找到有问题的Delayed::Backend::ActiveRecord::Job
实例后,一个puts my_job.handler
会显示:
object: !ruby/ActiveRecord:MyActiveRecord attributes: id: 7648 ... some good stuff ... my_field: ? bla bla bla ... some other good stuff ... method_name: :mail args: []
我首先想到这是一个编码问题,但我意识到’?’ 性格是一个真正的’?’ 字符(即值63)而不是对未识别字符的误解。
然后我尝试创建一个my_field
值为的活动记录类的新实例? Totot
? Totot
然后YAML看起来如下:
object: !ruby/ActiveRecord:MyActiveRecord attributes: id: 7648 ... some good stuff ... my_field: ! '? bla bla bla' ... some other good stuff ... method_name: :mail args: []
并且YAML.load(...)
成功运行。
所以我的问题是:
- 知道我的数据库中有多乱的YAML吗?
- 知道我应该如何消毒我的params以避免这样的问题?
- 知道如何在unit testing中重现这一点吗? (确定我实际上正在修改第2步)
@ house9建议的详细解释:
不要执行以下操作(即使delayed_job的git repo建议为例)
Notifier.delay.signup(@user) class NotifierMailer < ActionMailer::Base def signup(user) end end
因为这将尝试yaml编码@user
(这可能会导致问题)
但是,每当你有一个具有id的对象(尤其是AR对象)时,你应该在调用延迟的作业时传递id并在以后检索它:
Notifier.delay.signup(@user.id) class NotifierMailer < ActionMailer::Base def signup(id) @user = User.find_by_id(id) end end
知道我应该如何消毒我的params以避免这样的问题?
不要序列化您的activerecord对象,而只是序列化AR id,然后执行find作为作业的第一步。
不确定序列化AR损坏的原因,您的架构是否在序列化发生之前和作业运行之间发生了变化?
- Rails 5的ActiveRecord :: Migration中的是什么意思?
- 如何为Devise添加策略
- OmniAuth Facebook过期令牌错误
- 捕获Ruby on Rails应用程序的屏幕截图
- Rails RSpec请求规范失败,因为意外的%2F添加到重定向响应
- Rails AJAX – 获取下拉选项以填充表格
- 如何订购字母列表(“a”,“b”,“c”,…,“z”,“aa”,“ab”)? 字符串#sunk和在这种情况下似乎不能很好地协同工作
- 我正在使用rails cast omniauth,我收到此错误
- rails 3&activerecord:我是否需要采取特殊记录锁定预防措施来更新计数器字段?