2009-09-03 8 views

Respuesta

40

no hay incorporado en ActiveRecord validador de DateTime, pero puede agregar fácilmente este tipo de capacidad a un modelo ActiveRecord, sin necesidad de utilizar un plug-in, con algo como esto:

class Thing < ActiveRecord::Base 
    validate :happened_at_is_valid_datetime 

    def happened_at_is_valid_datetime 
    errors.add(:happened_at, 'must be a valid datetime') if ((DateTime.parse(happened_at) rescue ArgumentError) == ArgumentError) 
    end 
end 
+0

Perfecto, gracias Gabe. – Daniel

+0

Me alegra que esto haya ayudado. No es el código más glorioso, pero funciona. –

+0

Gracias, esto es genial. Intenté 'validates_timeliness' pero tuve problemas al utilizar getters y setters. Esto funcionó perfectamente. –

-2

Es absolutamente necesario validar fechas. Con los ayudantes de formulario predeterminados de Rails, puede seleccionar fechas como el 31 de septiembre. respuesta

+0

Validar la entrada del usuario a través de formularios es un buen comienzo, pero el contexto de la pregunta sugiere que el OP estaba preguntando sobre las validaciones del modelo de Rails. –

12

de Gabe no funcionó para mí, así que esto es lo que hice para validar mis fechas:

class MyModel < ActiveRecord::Base 
    validate :mydate_is_date? 

    private 

    def mydate_is_date? 
    if !mydate.is_a?(Date) 
     errors.add(:mydate, 'must be a valid date') 
    end 
    end 
end 

que solo estaba buscando para validar que la fecha es de hecho una cita, y no es una cadena, carácter, int, float, etc ...

Más validación de fechas complejo se puede encontrar aquí: https://github.com/codegram/date_validator

+1

La gema es la solución más fácil, tardé tres minutos en implementarla. No vale la pena escribir ningún código. –

+2

@MichaelSchmitz - Vale la pena escribir el código porque el código se explica por sí mismo: es posible que las personas que miran el código no sepan de la existencia de las gemas y añada una carga adicional para lo que es una tarea simple. – Toby

+0

@Toby - gracias por el puntero, tienes razón al respecto. Soy el único desarrollador por ahora, supongo que estaba feliz de que funcionó. –

1

Se puede crear un validador de fecha y hora personalizada por sí mismo

1) crear una carpeta llamada validadores en el interior del directorio de aplicaciones

2) crear un archivo de datetime_validator.rb. con el siguiente contenido dentro app/validadores directorio

class DatetimeValidator < ActiveModel::EachValidator 
    def validate_each(record, attribute, value) 
    if ((DateTime.parse(value) rescue ArgumentError) == ArgumentError) 
     record.errors[attribute] << (options[:message] || "must be a valid datetime") 
    end 
    end 
end 

3) Aplicar esta validación en el modelo

class YourModel < ActiveRecord::Base 
    validates :happend_at, datetime: true 
end 

4) Añadir la línea de abajo en application.rb

config.autoload_paths += %W["#{config.root}/app/validators/"] 

5) de reinicio su aplicación de rieles

Nota: El método anterior probado en rieles 4

6

Las versiones recientes de Rails tendrán type cast valores antes de la validación, por lo que los valores no válidos se pasarán como nil a los validadores personalizados. Estoy haciendo algo como esto:

# app/validators/date_time_validator.rb 
class DateTimeValidator < ActiveModel::EachValidator 
    def validate_each(record, attribute, value) 
    if record.public_send("#{attribute}_before_type_cast").present? && value.blank? 
     record.errors.add(attribute, :invalid) 
    end 
    end 
end 
# app/models/something.rb 
class Something < ActiveRecord::Base 
    validates :sold_at, date_time: true 
end 
# spec/models/something_spec.rb (using factory_girl and RSpec) 
describe Something do 
    subject { build(:something) } 

    it 'should validate that :sold_at is datetimey' do 
    is_expected.not_to allow_value(0, '0', 'lorem').for(:sold_at).with_message(:invalid) 
    is_expected.to allow_value(Time.current.iso8601).for(:sold_at) 
    end 
end 
Cuestiones relacionadas