2009-09-03 12 views

Odpowiedz

40

Nie ma wbudowaną ActiveRecord walidator dla DateTimes, ale łatwo można dodać tego rodzaju zdolności do modelu ActiveRecord, bez użycia wtyczki, ze coś takiego:

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

Doskonale, dzięki Gabe. – Daniel

+0

Cieszę się, że pomogło to. To nie jest najbardziej chwalebny kod, ale działa. –

+0

Dzięki, to jest świetne. Próbowałem 'validates_timeliness' ale miałem problemy z używaniem pobierających i ustawiających. To działało idealnie. –

-2

To całkiem niezbędne do walidacji Daktyle. Za pomocą domyślnych pomocników formularzy Railsowych można wybrać daty takie jak 31 września. Odpowiedź

+0

Sprawdzanie poprawności danych wprowadzanych przez użytkownika to dobry początek, ale kontekst pytania sugeruje, że PO pytał o zatwierdzenia modelu Rails. –

12

Gabe nie działa dla mnie, więc oto co zrobiłem, aby potwierdzić moje terminach:

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 

właśnie chce potwierdzić, że data jest w rzeczywistości data, a nie ciągiem znaków, charakter, int, float, etc ...

Bardziej skomplikowane walidacja datę można znaleźć tutaj: https://github.com/codegram/date_validator

+1

Klejnot jest najłatwiejszym rozwiązaniem, zajęło mi trzy minuty do realizacji. Nie warto napisać żadnego kodu. –

+2

@MichaelSchmitz - Warto napisać kod, ponieważ kod jest oczywisty - nowi ludzie, którzy patrzą na kod, mogą nie wiedzieć o istnieniu tego klejnotu i dodają dodatkowe obciążenie dla tego, co jest prostym zadaniem. – Toby

+0

@Toby - dzięki za wskaźnik, masz rację. Jestem teraz jedynym programistą, zgaduję, że byłem po prostu szczęśliwy, że zadziałało. –

1

Można utworzyć niestandardowe walidatora datetime przez siebie

1) Utwórz folder o nazwie weryfikatorów w wewnątrz aplikacji katalogu

2) Utwórz datetime_validator.rb pliku. o następującej treści wewnątrz aplikacji/Walidatory katalog

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) Zastosuj ten walidację modelu

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

4) Dodaj poniższy wiersz w environment.rb

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

5) Restart Twoja aplikacja szynowa

Uwaga: Powyższa metoda testowana w szynach 4

6

Ostatnie wersje Railsów będą miały wartości type cast przed sprawdzeniem poprawności, więc nieprawidłowe wartości zostaną przekazane jako nil s do niestandardowych weryfikatorów. Robię tak:

# 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