SerializationError Rails ActiveJob时间和日期

kdd*_*isz 14 ruby ruby-on-rails ruby-on-rails-4 rails-activejob

有人知道一种干净的方法来避免ActiveJob::SerializationError在尝试序列化DateTime对象时发生这种情况吗?

我到目前为止的两个解决方案是:

  • dump在加载参数时调用Marshal/JSON/YAML 然后load返回到Job(这很糟糕,因为我需要修补邮件程序作业)
  • 猴子补丁DateTime像这样:

/lib/core_ext/time.rb

class Time

  include GlobalID::Identification

  def id
    self.to_i
  end

  def self.find(id)
    self.at(id.to_i)
  end
end
Run Code Online (Sandbox Code Playgroud)

/lib/core_ext/date.rb

class Date

  include GlobalID::Identification

  def id
    self.to_time.id
  end

  def self.find(id)
    Time.find(id).to_date
  end
end
Run Code Online (Sandbox Code Playgroud)

哪个也很糟糕.谁有更好的解决方案?

Ant*_*y E 4

你真的需要序列化吗?如果它只是一个 Time/DateTime 对象,为什么不将参数编码并作为 Unix 时间戳原语发送呢?

>> tick = Time.now
=> 2016-03-30 01:19:52 -0400

>> tick_unix = tick.to_i
=> 1459315192

# Send tick_unix as the param...

>> tock = Time.at(tick_unix)
=> 2016-03-30 01:19:52 -0400
Run Code Online (Sandbox Code Playgroud)

请注意,这将精确到一秒之内。如果您需要 100% 的精确度,则需要将时间转换为有理数,并将分子和分母作为参数传递,然后Time.at(Rational(numerator, denominator)在作业中调用。

>> tick = Time.now
=> 2016-03-30 01:39:10 -0400

>> tick_rational = tick.to_r
=> (1459316350224979/1000000)

>> numerator_param = tick_rational.numerator
=> 1459316350224979

>> denominator_param = tick_rational.denominator
=> 1000000

# On the other side of the pipe...

>> tock = Time.at(Rational(numerator_param, denominator_param))
=> 2016-03-30 01:39:10 -0400

>> tick == tock
=> true
Run Code Online (Sandbox Code Playgroud)