2012-10-10 33 views
15

que posean un método age en mi modelo Waiver que parece:comparación de fecha con ActiveSupport :: TimeWithZone fallado

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 

Entonces tengo una especificación que se parece a:

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

Cuando ejecutar esta especificación consigo comparison of Date with ActiveSupport::TimeWithZone failed. ¿Qué estoy haciendo mal?

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

No sé por qué está fallando pero está trabajando muy bien si se configura a 'fecha_de_nacimiento 12.years.ago. to_date' y no '12.years.ago'. – oldergod

Respuesta

34

Usted está comparando una instancia de Date con una instancia de ActiveSupport::TimeWithZone en la expresión date < date_of_birth + age.years; ActiveSupport :: TimeWithZone es, according to the docs, una clase similar al tiempo que puede representar una hora en cualquier zona horaria. Simplemente no puede comparar los objetos Date y Time sin realizar algún tipo de conversión. Pruebe Date.today < Time.now en una consola; verá un error similar.

Expresiones como 12.years.ago y las marcas de tiempo ActiveRecord típicas son instancias de ActiveSupport :: TimeWithZone. Lo mejor es que se asegure de que solo se ocupa de objetos Time o objetos Date, pero no ambos en este método. Para hacer su comparación de fechas al día, en lugar de la expresión se puede escribir como:

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

Gracias por la explicación en profundidad. ¡He hecho los cambios apropiados a mi código y todo está funcionando bien ahora! –

+0

en realidad, puede comparar la fecha con TimeWithZone, pero parece que Rails convertirá Date a 00:00:00 UTC de manera predeterminada, lo que podría introducir errores. Es decir. >> 'Time.zone.parse ('Mar, 01 Ago 2017 00:00:00 CEST +02: 00') 'true' – Magne

Cuestiones relacionadas