class ActiveModel::Validations::TransitionValidator
Public Class Methods
new(options)
click to toggle source
Calls superclass method
# File lib/active_model/validations/transition_validator.rb, line 4 def initialize(options) super @column = options[:column].to_s valid_transitions = options[:valid_transitions] @when_validations = options[:when_validations] @inclusive = options[:inclusive] @allowed_transitions = {} build_valid_transition_lookup(valid_transitions) end
Public Instance Methods
build_valid_transition_lookup(valid_transitions)
click to toggle source
# File lib/active_model/validations/transition_validator.rb, line 15 def build_valid_transition_lookup(valid_transitions) valid_transitions.each do |transition| [transition[:from]].flatten.each do |from| [transition[:to]].flatten.each do |to| requires_validation = transition[:requires].present? requires_when = transition[:when].present? @allowed_transitions[from] ||= [] next @allowed_transitions[from] << { to => { requires_validation: false } } unless requires_validation @allowed_transitions[from] << { to => { requires_validation: true, requires_when: requires_when, requires: transition[:requires].map do |key, value| { key => [value].flatten } end } } end end end end
validate(record)
click to toggle source
# File lib/active_model/validations/transition_validator.rb, line 40 def validate(record) return true if @when_validations && when_condition_unmet?(record) return true unless record.persisted? changes = record.changes return true unless changes.has_key?(@column) column_change = changes[@column] original_value = column_change[0] new_value = column_change[1] valid_transitions = @allowed_transitions[original_value] if valid_transitions.nil? add_inclusion_errors(record, original_value, new_value) if @inclusive return true end transition = valid_transitions.find { |allowed_transition| allowed_transition[new_value] } return invalid_transition_error(record, original_value, new_value) unless transition requires_validation = transition[new_value][:requires_validation] return true unless requires_validation requires_validation_requirements = transition[new_value][:requires] validate_requires_field(requires_validation_requirements, original_value, new_value, record) end
Private Instance Methods
add_inclusion_errors(record, original_value, new_value)
click to toggle source
# File lib/active_model/validations/transition_validator.rb, line 69 def add_inclusion_errors(record, original_value, new_value) record.errors.add( @column.to_sym, "#{@column} cannot transition from #{original_value} to #{new_value}." ) end
add_requires_error(record, original_value, new_value, required_column_name, current_required_value)
click to toggle source
# File lib/active_model/validations/transition_validator.rb, line 103 def add_requires_error(record, original_value, new_value, required_column_name, current_required_value) record.errors.add( @column.to_sym, "#{@column} cannot transition from #{original_value} to #{new_value} while #{required_column_name} is #{current_required_value}" ) end
invalid_transition_error(record, original_value, new_value)
click to toggle source
# File lib/active_model/validations/transition_validator.rb, line 96 def invalid_transition_error(record, original_value, new_value) record.errors.add( @column.to_sym, "#{@column} cannot transition from #{original_value} to #{new_value}" ) end
validate_requires_field(all_requires, original_value, new_value, record)
click to toggle source
# File lib/active_model/validations/transition_validator.rb, line 85 def validate_requires_field(all_requires, original_value, new_value, record) all_requires.each do |requirement| requirement.map do |attribute, allowed_values| current_value = record.read_attribute(attribute) next if allowed_values.include?(current_value) add_requires_error(record, original_value, new_value, attribute, current_value) end end end
when_condition_unmet?(record)
click to toggle source
# File lib/active_model/validations/transition_validator.rb, line 76 def when_condition_unmet?(record) met_conditions = @when_validations.map do |attribute, when_values| current_value = record.read_attribute(attribute) [when_values].flatten.include?(current_value) end !met_conditions.all?(true) end