ActiveModel Interdependence
Specify that validations depend on the validation of other fields
Lets classes that implement ActiveModel::Model or ActiveModel::Validator
specify that they are dependent on other fields being valid. These specifications
are translated into a dependency graph, sorted, and applied in order to a model.
As a result, fields are only validated once the fields that they depend on are
validated.
Install
Simply run
gem install activemodel-interdependence
or add activemodel-interdependence to your gemfile
gem 'activemodel-interdependence'
and run bundle install from your shell.
Usage
class DayValidator < ActiveModel::EachValidator
validates :month_field, inclusion: 1..12
validates :year_field, inclusion: 0..2015
def validate_each(record, attribute, value)
month = dependency(record, :month_field)
year = dependency(record, :year_field)
return if (1..Time.days_in_month(month, year)).cover?(value)
record.errors[attribute] << "is not valid for the month #{Date::MONTHNAMES[month]}"
end
def dependency(record, proxy_name)
name = .fetch(:dependencies, {}).fetch(proxy_name)
record.send(name)
end
end
class Birthday
include ActiveModel::Model
attr_accessor :day, :month, :year
validates :day, day: {
dependencies: {
month_field: :month,
year_field: :year
}
}
end
leap_day = Birthday.new(day: 29, month: 2, year: 2000)
leap_day.valid? # => true
not_a_leap_day = Birthday.new(day: 29, month: 2, year: 1999)
not_a_leap_day.valid? # => false
not_a_leap_day.errors. # => ["Day is not valid for the month February"]
bad_month = Birthday.new(day: 29, month: 0, year: 1999)
bad_month.valid? # => false
bad_month.errors. # => ["Month is not included in the list"]
License
activemodel-interdependence is released under the MIT license. See LICENSE for details.
