自回答の転記
やりたいこと
モデルにバリデーションを掛けて、open_day
が今日ではなく昨日以前であった場合に、エラーにしたい
テストコードと実装
仮に Post
モデルとして話を進めていく
テストコード
# == Schema Information # # Table name: posts # # id :integer not null, primary key # open_day :date # created_at :datetime not null # updated_at :datetime not null # RSpec.describe Post, type: :model do context 'validation about open_day' do before { Timecop.travel(2018, 1, 2).freeze } it 'invalid: when before today' do post = Post.new(open_day: Date.today.advance(days: -1)) expect(post).to_not be_valid end it 'valid: when today or after' do post = Post.new(open_day: Date.today.advance(days: 1)) expect(post).to be_valid end it 'invalid: when empty value' do post = Post.new expect(post).to_not be_valid end after { Timecop.return } end end
実装
# == Schema Information # # Table name: posts # # id :integer not null, primary key # open_day :date # created_at :datetime not null # updated_at :datetime not null # class Post < ApplicationRecord validate :not_before_today def not_before_today errors.add(:open_day, 'Please set today or after today') if open_day.nil? || open_day < Date.today end end
Links
- Module: RSpec::Rails::Matchers#be_valid — Documentation for rspec-rails (3.7.2)
- Date#advance - Ruby on Rails API
- travisjeffery/timecop: A gem providing "time travel", "time freezing", and "time acceleration" capabilities, making it simple to test time-dependent code. It provides a unified method to mock Time.now, Date.today, and DateTime.now in a single call. - GitHub
- ctran/annotate_models: Annotate Rails classes with schema and routes info - GitHub