将日期序列化为 YAML rails

Serialise hash with dates as YAML rails

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 class,它有一个带有散列的 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 应用程序解析,该应用程序轮询数据库以检查新条目,并且引号似乎打破反序列化(抛出 java.lang.Exception: BaseProperties.getdate());如果我手动编辑该字段以删除引号,该应用程序将按预期运行。如何防止添加这些引号?

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

好处是serialize接受两个参数,第二个是序列化器class

那么,您需要做的就是:

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

并实施 MyYaml,委托一切,将 date/time 保存到 YAML 并为他们生产任何你需要的东西。

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