Module: ConstancyValidation::ClassMethods

Defined in:
lib/validates_constancy/constancy_validation.rb

Overview

The following validation is defined in the class scope of the model that you’re interested in validating. It offers a declarative way of specifying when the model is valid and when it is not.

Instance Method Summary collapse

Instance Method Details

#validates_constancy_of(*attribute_names) ⇒ Object

Encapsulates the pattern of wanting to protect one or more model attributes from being changed after the model object is created. Example:

class Person < ActiveRecord::Base

  # Prevent changes to Person#user_name and Person#member_since.
  validates_constancy_of :user_name, :member_since

end

This check is performed only on update.

Configuration options:

:message

A custom error message (default is: “can’t be changed”)

:if

Specifies a method, Proc or string to call to determine if the validation should occur (e.g., :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The method, Proc or string should return or evaluate to true or false.

Warning: With associations, validate the constancy of a foreign key, not the instance variable itself: validates_constancy_of :invoice_id instead of validates_constancy_of :invoice.

Also note the warning under Inheritable callback queues in api.rubyonrails.org/classes/ActiveRecord/Callbacks.html. “In order for inheritance to work for the callback queues, you must specify the callbacks before specifying the associations. Otherwise, you might trigger the loading of a child before the parent has registered the callbacks and they won’t be inherited.” Validates Constancy uses these callback queues, so you’ll want to specify associations after validates_constancy_of statements in your model classes.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/validates_constancy/constancy_validation.rb', line 44

def validates_constancy_of(*attribute_names)
  options = {:message => Object.const_defined?(:I18n) ?
             I18n.translate('activerecord.errors.messages.constancy') :
             ActiveRecord::Errors.default_error_messages[:constancy]}
  options.merge!(attribute_names.pop) if attribute_names.last.kind_of?(Hash)
  
  constant_names = base_class.instance_variable_get(:@constant_attribute_names) ||
                   []
  constant_names.concat attribute_names.collect!(&:to_s)
  base_class.instance_variable_set :@constant_attribute_names,
                                   constant_names
  
  ConstancyValidation::OriginalAttributesCapture.extend self
  
  options.merge! :on => :update
  validates_each(attribute_names, options) do |record, attribute_name, value|
    unless value ==
           record.instance_variable_get(:@original_attributes)[attribute_name]
      record.errors.add attribute_name, options[:message]
    end
  end
  
  self
end