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
Thanks. Seems to work quite nicely!