Проверка даты в Rails 3 - PullRequest
       5

Проверка даты в Rails 3

6 голосов
/ 19 ноября 2010

У меня есть приложение на Rails 3 (использующее Mongodb и Mongoid, если это имеет значение), и в одной из моих моделей у меня есть поле, определенное как тип Date.

class Participant
  include Mongoid::Document

  field :birth_date, :type => Date
end

Мой контроллер использует функцию find_or_initialize_by mongo:

class ParticipantController

  def create
    @participant = Participant.find_or_initialize_by(params[:participant])
    if @participant.save
      redirect_to participants_path
    else
      render :new
    end
  end
end

Все это сводится к: как мне проверить дату в ActiveModel с Mongoid и Rails 3?

Я хочу убедиться, что ввод «бла», как в текстовом поле, не выдает исключение при назначении в поле .birth_date моей модели. Это должно обеспечить хорошее сообщение об ошибке проверки без использования контроллера для проверки.

Вот основные требования:

  • Представление должно быть одним текстовым полем. Ничего больше. Это пользователь требование, что мы не можем изменить

  • Проверка должна быть сделана в модель, не в контроллере или
    просмотр (JavaScript или любой другой)

  • Нет проверок формата регулярных выражений (они не работают правильно / поддерживают локали и т. Д.)

Проблема в том, что значение из текстового поля присваивается .birth_date до запуска validates_format_of и validates_presence_of. так что ...

как мне перехватить присвоение значения, чтобы я мог проверить его до того, как оно будет присвоено? Можно ли сделать это в модели, используя ActiveModel? или это требует от меня ввода кода в контроллер для этого?

Ответы [ 5 ]

8 голосов
/ 19 ноября 2010

Этот небольшой блок кода может помочь

retVal = "it is a date"
begin
  y = Date.parse("rodman was here")
rescue
  retVal = "nope not a date"
end

puts retVal
4 голосов
/ 06 августа 2012

Драгоценный камень validates_timeliness довольно сладок. Вы можете просто сделать что-то вроде этого:

class Participant < ActiveRecord::Base
  validates_date :birth_date
end
2 голосов
/ 31 июля 2011

Вам необходимо использовать фильтр before_validation, например, для в вашей модели

class Participant
  include Mongoid::Document
  before_validation :make_a_date
  field :birth_date, :type => Date

  private
  def make_a_date
    #do all sorts of manipulation of the date here
  end
end

другой альтернативой будет создание собственного метода проверки? Но я не думаю, что ты этого хочешь ...

2 голосов
/ 10 марта 2011

Я только что нашел это, хотя я еще не играл с ним:

http://blog.codegram.com/2011/2/date-validation-with-rails-3

Хранилище Github находится в https://github.com/codegram/date_validator

Цитата изсообщение в блоге:

"Вы можете использовать его либо в моделях Rails 3, либо в любом пользовательском классе (после использования ActiveModel), действительно простым способом

Они такжеприведите пример, который создает впечатление, что он должен работать на вас - это сделано в модели, а не в контроллере.

validates expiration_date,
    :date => { :after => Time.now, :before => Time.now + 1.year }
0 голосов
/ 18 марта 2012

Альтернативой является создание класса проверки, который расширяет ActiveModel :: EachValidator, например ::

.
class TimeValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    if value && !value.kind_of?(Time)
      record.errors[attribute] << (options[:message] || "don't recognise time")
    end
  end
end

В приведенном выше примере я связываю это с методом установки в модели, который обрабатывает синтаксический анализ, если передается строка. Я хотел поддержать нечеткое сопоставление времени и даты, поэтому я использую Chronic .

require 'chronic'

def starts_at=(value)
  if value.kind_of?(String) && parsed_time = Chronic.parse(value)
    @starts_at = parsed_time.utc
  else
    @starts_at = value
  end
end

и это для настройки валидатора на модели

validates :starts_at, :time => true

Что красиво и условно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...