1

I found a few duplicate Q&As; however, I did not figure it out.

I have House model which has :available_at validation (The field is Date). I'm trying to achieve something like this.

The availability date must be in future.

# db/schema.rb
create_table "houses", force: :cascade do |t|
  # ...
  t.date "available_at", null: false
  # ...
end

# app/models/house.rb
class House < ApplicationRecord
  validates :available_at, presence: true, if: -> { available_at.future? }
end

Also, here is the PR


Duplicate answers
Conditional Validation RAILS MODEL
Conditional validation if another validation is valid
Rails validate uniqueness only if conditional
rails date validation with age
How do I validate a date in rails?
https://codereview.stackexchange.com/questions/110262/checking-for-valid-date-range-in-rails

strivedi183
  • 4,749
  • 2
  • 31
  • 38

2 Answers2

1

Thank you for Mark Merritt because I inspired his answer. The answer works as expected, but the problem is keeping the model DRY, and also, it has a long method name.

I created separate validator which is name at_future_validator.rb. I placed the file inside of lib/validators folder.

Then, I wrote this validator

# lib/validators/at_future_validator.rb
class AtFutureValidator < ActiveModel::EachValidator
  def validate_each(object, attribute, value)
    if attribute.present? && value < Date.today
      object.errors[attribute] << (options[:message] || 'must be in the future')
    end
  end
end

OK. The first part has done. The important part is, which I saw now on the guide, working with custom validator which we named at_future_validator. We need to require the validator inside of the house model.

# app/models/house.rb
class House < ApplicationRecord
  require_dependency 'validators/at_future_validator'
  # ...
  validates :available_at, presence: true, at_future: true
  # ...
end

Guides that I followed
#211 Validations in Rails 3 - 8:09

Community
  • 1
  • 1
0

This seems like a good use case for a custom method that validates available_at...

class House < ApplicationRecord
  validate :available_at_is_in_the_future

  def available_at_is_in_the_future
    if available_at.present? && available_at <= Date.today
      errors.add(:available_at, "must be in the future")
    end
  end
end
Mark Merritt
  • 2,625
  • 2
  • 12
  • 16