2012-10-10 9 views
15

Ich habe eine age Methode auf meinem Waiver Modell, das wie folgt aussieht:Vergleich von Date mit Active :: TimeWithZone fehlgeschlagen

def age(date = nil) 

    if date.nil? 
     date = Date.today 
    end 
    age = 0 
    unless date_of_birth.nil? 
     age = date.year - date_of_birth.year 
     age -= 1 if date < date_of_birth + age.years #for days before birthday 
    end 
    return age 
    end 

ich dann eine Spezifikation haben, die wie folgt aussieht:

it "calculates the proper age" do 
waiver = FactoryGirl.create(:waiver, date_of_birth: 12.years.ago) 
waiver.age.should == 12 
end 

Als ich Führen Sie diese Spezifikation Ich bekomme comparison of Date with ActiveSupport::TimeWithZone failed. Was mache ich falsch?

Failures: 

    1) Waiver calculates the proper age 
    Failure/Error: waiver.age.should == 12 
    ArgumentError: 
     comparison of Date with ActiveSupport::TimeWithZone failed 
    # ./app/models/waiver.rb:132:in `<' 
    # ./app/models/waiver.rb:132:in `age' 
    # ./spec/models/waiver_spec.rb:23:in `block (2 levels) in <top (required)>' 
+0

Ich weiß nicht, warum es fehlschlägt, aber es funktioniert gut, wenn Sie DATE_OF_BIRTH auf '12.years.ago gesetzt. to_date' und nicht '12years.ago'. – oldergod

Antwort

34

Sie vergleichen eine Instanz von Date mit einer Instanz von ActiveSupport::TimeWithZone im Ausdruck date < date_of_birth + age.years; ActiveSupport :: TimeWithZone ist according to the docs, eine zeitartige Klasse, die eine Zeit in einer beliebigen Zeitzone darstellen kann. Sie können Date und Time Objekte einfach nicht vergleichen, ohne eine Art von Konvertierung durchzuführen. Versuchen Sie Date.today < Time.now auf einer Konsole; Sie werden einen ähnlichen Fehler sehen.

Ausdrücke wie 12.years.ago und typische ActiveRecord-Zeitstempel sind Instanzen von ActiveSupport :: TimeWithZone. Sie sollten sicherstellen, dass Sie nur mit Objekten Time oder Date Objekte arbeiten, aber nicht beide in dieser Methode. Ihr Vergleichsdatum auf dem neuesten Stand zu machen, könnte der Ausdruck stattdessen geschrieben werden als:

age -= 1 if date < (date_of_birth + age.years).to_date 
+0

Danke für die eingehende Erklärung. Ich habe die entsprechenden Änderungen an meinem Code vorgenommen und alles funktioniert jetzt einwandfrei! –

+0

tatsächlich, können Sie Datum mit TimeWithZone vergleichen, aber es scheint, Rails wird Datum in 00:00:00 UTC standardmäßig dann konvertieren, die Bugs einführen könnte. Ie. >> 'Time.zone.parse ('Di, 01 Aug 2017 00:00:00 CEST +02: 00') 'true' – Magne

Verwandte Themen