ActiveRecord disallow changes using unchangeable validation

Not allowing changes to be made to e.g. the login of the user only by the UI is in my eyes not enough.
The model should also ensure, that changes cannot be made once assigned.

So i tried to find an validation that does this for me.
But the once i found did not quite work as i expected.

So i wrote my own that i want to share:

class User < ActiveRecord::Base
  validates_unchangeable :login
end

unchangeable_validation.rb

require 'active_support/concern'
require 'active_model'
require 'active_record/base'

module UnchangeableValidation
  extend ActiveSupport::Concern

  class UnchangeableValidator < ActiveModel::EachValidator

    def initialize(options)
      super(options)
    end

    def validate_each(object, attribute, value)
      if(!object.new_record? && value.present?)
        abChanged = attribute.to_s + "_changed?"
        if(object.send(abChanged.to_sym))
          object.errors[attribute] << (options[:message] || "cannot be changed once assigned")
        end
      end
    end
 end

 module ClassMethods

   def validates_unchangeable(*attr_names)
     validates_with UnchangeableValidation::UnchangeableValidator, _merge_attributes(attr_names)
   end
 end
end

ActiveRecord::Base.send(:include, UnchangeableValidation)

unchangeable_validation_test.rb

require 'test_helper'

class UnchangeableValidationTest <  ActiveSupport::TestCase

  def test_login_unchangeable
    instance = User.new
    instance.login = "login"
    instance.save!
    instance.login = "changed"
    instance.save
    assert_equal instance.errors[:login].first, "cannot be changed once assigned"
  end

end
Print Friendly, PDF & Email

Tags: , ,

One Response to “ActiveRecord disallow changes using unchangeable validation”

  1. Funvector sagt:

    Thanks. Seems to work quite nicely!

Leave a Reply

Time limit is exhausted. Please reload CAPTCHA.