15

またはオブジェクトActiveJob::SerializationErrorをシリアル化しようとしたときに発生するを回避するクリーンな方法を知っている人はいますか?DateTime

私がこれまでに持っていた2つの解決策は次のとおりです。

  • dump引数をロードするときにMarshal/JSON/YAML を呼び出しloadてから、Job に戻します (これは、メーラー ジョブにモンキー パッチを適用する必要があるためです)。
  • モンキーパッチ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

これもひどい。誰もがより良い解決策を持っていますか?

4

1 に答える 1

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

これは 1 秒以内の精度になることに注意してください。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
于 2016-03-30T05:23:20.137 に答える