СериализацияError Rails ActiveJob Время и дата

Кто-нибудь знает о чистом способе избежать ActiveJob::SerializationError, который возникает при попытке сериализации объекта Date или Time?

Два решения, которые у меня были до сих пор, состоят в следующем:

  • Вызов маршала /JSON/YAML dump при загрузке аргументов, а затем load обратно в задание (что отстойно, потому что мне нужно, чтобы обезьяна исправляла задание почтовой программы)
  • Патч обезьяны Date и Time следующим образом:

/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

/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

Который также отстой. У кого-то есть лучшее решение?

Ответы

Ответ 1

Вам действительно нужна сериализация? Если это просто объект 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

Обратите внимание, что это будет точно в течение одной секунды. Если вам нужна точная точность 100%, вам нужно будет преобразовать время в Rational и передать как числитель, так и знаменатель в качестве параметров, а затем вызвать 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