SerializationError Rails活动作业时间和日期

时间:2020-12-08 01:16:35

Anyone know of a clean way to avoid the ActiveJob::SerializationError that occurs when trying to serialize a Date or Time object?

有人知道一种避免ActiveJob::SerializationError的干净方法吗?

The two solutions I've had so far are to:

到目前为止,我有两个解决方案:

  • Call Marshal/JSON/YAML dump when loading the arguments and then load back in the Job (which sucks because I need to monkey patch the mailer job)
  • 在加载参数时调用Marshal/JSON/YAML转储,然后在作业中重新加载(这很糟糕,因为我需要对mailer作业进行修改)
  • Monkey patch Date and Time like so:
  • 猴子补丁的日期和时间如下:

/lib/core_ext/time.rb

/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

/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

Which also sucks. Anyone have a better solution?

也很糟糕。谁有更好的解决方案?

1 个解决方案

#1


3  

Do you really need serialization? If it's just a Time/DateTime object, why not just encode and send your parameter as a Unix timestamp primitive?

您真的需要序列化吗?如果它只是一个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

Note this will be accurate to within one second. If you need 100% exact accuracy you'll need to convert the time to a Rational and pass both the numerator and denominator as params and then call Time.at(Rational(numerator, denominator) within the job.

注意这将在一秒内准确无误。如果你需要100%精确的精度,你需要把时间转换成一个有理数,把分子和分母作为参数传递,然后调用时间。在(分子,分母)上。

>> 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

#1


3  

Do you really need serialization? If it's just a Time/DateTime object, why not just encode and send your parameter as a Unix timestamp primitive?

您真的需要序列化吗?如果它只是一个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

Note this will be accurate to within one second. If you need 100% exact accuracy you'll need to convert the time to a Rational and pass both the numerator and denominator as params and then call Time.at(Rational(numerator, denominator) within the job.

注意这将在一秒内准确无误。如果你需要100%精确的精度,你需要把时间转换成一个有理数,把分子和分母作为参数传递,然后调用时间。在(分子,分母)上。

>> 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