実装内容
掲示板に開始時刻と終了時刻を設定し、人を募集するサイトを作成する。終了時間が開始時間より前にならないようにバリデーションを設定する。(※ついでに、開始時刻が現在日時より前にならないバリデーションも付ける)
環境
Ruby 2.5.0
Rails 6.0.3.4
前提
募集板を作成する時、開始時刻と終了時刻を入力できるように設定しておく。
実際のコード
今回は、募集版をboardと置く。
テーブルの内容は↓の通り
class CreateBoards < ActiveRecord::Migration[6.0]
def change
create_table :boards do |t|
(中略)
t.datetime :start_time, null: false
t.datetime :finish_time, null: false
t.timestamps
end
end
end
開始時間を「start_time」カラムに、終了時間を「finish_time」カラムに設定。
※終了時間は「end_time」でも良かったんですが、「end」を入力する度に、インデントが変わる現象が発生してしまい(恐らくエディタの設定)鬱陶しかったので、「finish_time」にしました。
モデル
以下のようなバリデーションを設定しました。
※一部抜粋しています
validates :start_time, presence: true
validates :finish_time, presence: true
validate :start_finish_check
validate :start_check
def start_finish_check
errors.add(:finish_time, "は開始時刻より遅い時間を選択してください") if self.start_time > self.finish_time
end
def start_check
errors.add(:start_time, "は現在の日時より遅い時間を選択してください") if self.start_time < Time.now
end
それぞれ、軽く解説いたします。
validate :start_finish_check
validate :start_check
ここで、それぞれの処理を検証しています。validates
ではなく、validate
になっていることに注意してください。validate
になっていると、「You need to supply at least one validation」と言うエラーが出ます。
def start_finish_check
errors.add(:finish_time, "は開始時刻より遅い時間を選択してください") if self.start_time > self.finish_time
#↑ で開始時間と終了時間の比較
end
def start_check
errors.add(:start_time, "は現在の日時より遅い時間を選択してください") if self.start_time < Time.now
#↑ で開始時間と現在日時の比較
end
ここで、それぞれの時間を比較しています。if
が真だった場合は、エラー文が追加されます。書くまでもありませんが、不等号>
の向きや、if
をunless
と書き換えて書くことも可能です。また、self
を書かなくても同様の処理が行われます。
その辺は、お好みで。
時間の取得
今回はDatetime型の比較でしたが、他の型の場合も同様に実装できると思います。
↓が日時取得の参考記事です
rubyで現在日時を取得する
[RubyとRailsにおけるTime, Date, DateTime, TimeWithZoneの違い]
(https://qiita.com/jnchito/items/cae89ee43c30f5d6fa2c)
参考記事
railsでdatetime型の前後入力のバリデーションをかける方法
【バリデーション】rails 今日の日付以降を指定する方法