2015-04-16 12 views
14

Ktoś wie w czysty sposób, aby uniknąć ActiveJob::SerializationError, który występuje podczas próby serializacji obiektu Date lub Time?SerializationError Rails ActiveJob Data i godzina

dwóch rozwiązań, jakie miałem do tej pory to:

  • połączeń marszałek/JSON/YAML dump podczas ładowania argumenty a następnie load powrotem w pracy (co jest do bani bo muszę małpy łaty praca Mailer)
  • Monkey łata Date i Time tak:

/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 

które zasysa również. Ktoś ma lepsze rozwiązanie?

+2

Czy rzeczywiście należy przekazać tylko datę lub godzinę do pracy (i dlaczego)? Myślę, że byłoby lepiej przekazać ActiveModel jako parametr do zadania, prawdopodobnie zawierający instancję Date lub Time. (ActiveModels to GlobalID :: Identification, dzięki czemu można je szeregować) – sourcx

+0

Nie, to naprawdę nie jest konieczne. To po prostu wygodne. A ponadto działało z DelayedJob zanim zintegrowaliśmy ActiveJob. Więc ... wydaje się głupim, że będę musiał zmienić kod, aby zintegrować się z czymś, co po prostu ma być abstrakcyjne, a nie zmieniać funkcji. – kddeisz

+0

Dodajesz tylko obiekt Date/Time? Nic więcej? AFAIK, ActiveJob w rzeczywistości nazywa Marszałka serializacją twojego obiektu i potrzebuje czegoś takiego jak łatka małpy, którą powiedziałeś, aby móc odzyskać i przypomnieć sobie ten obiekt później. Czy możesz opublikować swój Mailer? – lsdr

Odpowiedz

3

Naprawdę potrzebujesz serializacji? Jeśli jest to tylko obiekt Time/DateTime, dlaczego nie wystarczy zakodować i wysłać swojego parametru jako prymitywu uniksowego timestamp?

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

Pamiętaj, że będzie to dokładne z dokładnością do jednej sekundy. Jeśli potrzebujesz 100% dokładności, musisz przekonwertować czas na Rational i przekazać zarówno licznik, jak i mianownik jako parametry, a następnie zadzwonić pod numer Time.at(Rational(numerator, denominator) w ramach zadania.

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

Wiem, że istnieje wiele sposobów na zrobienie tego poprzez zmianę wartości, zastanawiałem się tylko, czy istnieje sposób, aby to zrobić w połączeniu z serializacją innych obiektów. Jak w stanie przekazać 'my_method (data, czas, model)' i sprawić, żeby działało. W tym momencie jest to dość przestarzałe, ponieważ to pytanie zostało zadane prawie rok temu. – kddeisz

Powiązane problemy