1. ホーム
  2. ruby-on-rails

[解決済み] railsで日付の検証を行うには?

2023-02-04 13:18:33

質問

Ruby on Railsのモデルで日付を検証したいのですが、日、月、年の値がモデルに到達するまでにすでに不正確な日付に変換されています。

例えば、ビューで2009年2月31日と入力した場合、モデルで Model.new(params[:model]) を使用すると、それは "March 3rd 2009" に変換され、モデルはそれを有効な日付と見なしますが、それは不正確です。

この検証をモデルで行えるようにしたいと思います。できる方法はありますか、それとも完全に間違っているのでしょうか。

私はこの"を見つけました。 日付の検証 を見つけ、その問題を議論しましたが、解決されませんでした。

どのように解決するのですか?

を使っているのでしょう。 date_select ヘルパーを使用していると思います。他の方法としては、日、月、年のフィールドにselect formヘルパーを使用することです。こんな感じです(使用した例は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.