序列化哈希,日期为YAML rails

时间:2018-01-02 16:43:17

标签: ruby-on-rails ruby serialization rails-upgrade

TL; DR :Rails 5.1,Ruby 2.4.0将包含时间对象的哈希序列化,并在时间的字符串表示周围加上引号。这些引用不存在于Rails 2.3,Ruby 1.8.7中并且破坏了我的应用程序;我怎么摆脱它们?

背景和细节

我正在将应用程序从Rails 2.3,Ruby 1.8.7升级到Rails 5.1,Ruby 2.4.0。 我有一个ReportService类,它有一个report_params构造函数参数,它接受一个哈希值。创建这些对象后,此哈希将以YAML格式序列化。

class ReportService < ApplicationRecord
  # irrelevant AR associations omitted
   serialize :report_params
   serialize :output_urls
end

用户提交一个表单,其中包含他们想要运行的报表的详细信息,包括使用Time.parse()解析的字符串,该字符串将作为构造函数参数传递;所以代码(以程序形式删除不相关的细节,省略了许多无关的东西)看起来像

offset = customer.timezone.nil? ? '+0000' : customer.timezone.formatted_offset(:time => start_date)
params[:date_from] = Time.parse("#{start_date} #{params[:hour_from]}:{params[:min_from]} #{offset}").utc.strftime('%Y-%m-%d %H:%M:%S')
report_args = {...
                report_params: { ...
                                 date: params[:date_from]
                               }
               }
ReportService.create(report_args)

当我查看我的MYSQL数据库时,发现我的report_params字段看起来像... date_from: '2017-12-27 00:00:00' ...。旧版本中的相应代码生成的结果类似于... date_from: 2017-12-27 00:00:00 ...。这是一个坏事,因为该字段中的YAML被一个(遗留的)Java应用程序解析,该应用程序轮询数据库以检查新条目,并且引号似乎打破了反序列化(抛出{ {1}});如果我手动编辑该字段以删除引号,该应用程序将按预期工作。如何防止添加这些引号?

1 个答案:

答案 0 :(得分:2)

Rails5.1 / Ruby2.4执行更正,因为2017-12-27 00:00:00不是有效的yaml值。

好消息是serialize接受两个参数,第二个是一个序列化程序类

所以,你需要做的就是:

class ReportService < ApplicationRecord
  # irrelevant AR associations omitted
   serialize :report_params, MyYaml
   serialize :output_urls, MyYaml
end

并实施MyYaml,委派所有内容,将date / time保存到YAML并为您生成所需内容。

以上内容适用于任何格式的序列化数据,它完全与格式无关。 Examples