program tip

Rails에서 날짜를 어떻게 확인합니까?

radiobox 2020. 9. 6. 09:18
반응형

Rails에서 날짜를 어떻게 확인합니까?


Ruby on Rails에서 모델의 날짜를 확인하고 싶지만 일, 월 및 연도 값이 모델에 도달 할 때 이미 잘못된 날짜로 변환되었습니다.

예를 들어, 내보기에 2009 년 2 월 31 일을 입력하면 Model.new(params[:model])컨트롤러에서 사용할 때 "2009 년 3 월 3 일"로 변환됩니다. 그러면 내 모델이 유효한 날짜로 간주되지만 정확하지 않습니다.

내 모델에서이 유효성 검사를 수행하고 싶습니다. 내가 할 수있는 방법이 있습니까? 아니면 완전히 잘못된 것입니까?

문제를 설명하는 " 날짜 유효성 검사 "를 찾았 지만 해결되지 않았습니다.


date_select도우미를 사용 하여 날짜에 대한 태그를 생성하고 있다고 생각합니다 . 할 수있는 또 다른 방법은 일, 월, 연도 필드에 대한 선택 양식 도우미를 사용하는 것입니다. 다음과 같이 (내가 사용한 예는 created_at 날짜 필드입니다) :

<%= f.select :month, (1..12).to_a, selected: @user.created_at.month %>
<%= f.select :day, (1..31).to_a, selected: @user.created_at.day %>
<%= f.select :year, ((Time.now.year - 20)..Time.now.year).to_a, selected: @user.created_at.year %>

그리고 모델에서 날짜를 확인합니다.

attr_accessor :month, :day, :year
validate :validate_created_at

private

def convert_created_at
  begin
    self.created_at = Date.civil(self.year.to_i, self.month.to_i, self.day.to_i)
  rescue ArgumentError
    false
  end
end

def validate_created_at
  errors.add("Created at date", "is invalid.") unless convert_created_at
end

플러그인 솔루션을 찾고 있다면 validates_timeliness 플러그인을 확인 하겠습니다 . 다음과 같이 작동합니다 (github 페이지에서).

class Person < ActiveRecord::Base
  validates_date :date_of_birth, on_or_before: lambda { Date.current }
  # or
  validates :date_of_birth, timeliness: { on_or_before: lambda { Date.current }, type: :date }
end 

사용 가능한 유효성 검사 방법 목록은 다음과 같습니다.

validates_date     - validate value as date
validates_time     - validate value as time only i.e. '12:20pm'
validates_datetime - validate value as a full date and time
validates          - use the :timeliness key and set the type in the hash.

만성 보석 사용 :

class MyModel < ActiveRecord::Base
  validate :valid_date?

  def valid_date?
    unless Chronic.parse(from_date)
      errors.add(:from_date, "is missing or invalid")
    end
  end

end

Rails 3 또는 Ruby 1.9 호환성을 원한다면 date_validator gem을 사용 해보세요 .


Active Record gives you _before_type_cast attributes which contain the raw attribute data before typecasting. This can be useful for returning error messages with pre-typecast values or just doing validations that aren't possible after typecast.

I would shy away from Daniel Von Fange's suggestion of overriding the accessor, because doing validation in an accessor changes the accessor contract slightly. Active Record has a feature explicitly for this situation. Use it.


Since you need to handle the date string before it is converted to a date in your model, I'd override the accessor for that field

Let's say your date field is published_date. Add this to your model object:

def published_date=(value)
    # do sanity checking here
    # then hand it back to rails to convert and store
    self.write_attribute(:published_date, value) 
end

A bit late here, but thanks to "How do I validate a date in rails?" I managed to write this validator, hope is useful to somebody:

Inside your model.rb

validate :date_field_must_be_a_date_or_blank

# If your field is called :date_field, use :date_field_before_type_cast
def date_field_must_be_a_date_or_blank
  date_field_before_type_cast.to_date
rescue ArgumentError
  errors.add(:birthday, :invalid)
end

Here's a non-chronic answer..

class Pimping < ActiveRecord::Base

validate :valid_date?

def valid_date?
  if scheduled_on.present?
    unless scheduled_on.is_a?(Time)
      errors.add(:scheduled_on, "Is an invalid date.")
    end
  end
end

You can validate the date and time like so (in a method somewhere in your controller with access to your params if you are using custom selects) ...

# Set parameters
year = params[:date][:year].to_i
month = params[:date][:month].to_i
mday = params[:date][:mday].to_i
hour = params[:date][:hour].to_i
minute = params[:date][:minute].to_i

# Validate date, time and hour
valid_date    = Date.valid_date? year, month, mday
valid_hour    = (0..23).to_a.include? hour
valid_minute  = (0..59).to_a.include? minute
valid_time    = valid_hour && valid_minute

# Check if parameters are valid and generate appropriate date
if valid_date && valid_time
  second = 0
  offset = '0'
  DateTime.civil(year, month, mday, hour, minute, second, offset)
else
  # Some fallback if you want like ...
  DateTime.current.utc
end

Have you tried the validates_date_time plug-in?

참고URL : https://stackoverflow.com/questions/597328/how-do-i-validate-a-date-in-rails

반응형