ruby-on-railsvalidationactivemodel

Checking if attribute_changed? in ActiveModel::EachValidator


I have a class Person that has first_name, middle_name, last_name. I have a customed Each validator for these 3 attributes like so

validates :first_name, :middle_name, :last_name, nameValidator: true

In this validator I want to check if any one of these 3 attributes changed and given a few more conditions I'll validate name. For that I'm trying attribute_changed? but it doesn't work.

I've checked different methods from ActiveModel::Dirty and Activerecod::Dirty but nothing seems to work to check changes in each attribute. What am I missing?

module Person
  class nameValidator < ActiveModel::EachValidator

    def validate_each(record, attribute, value)
      return unless can_normalize?(record)
      #Normalization code 
    end

   def can_normalize?(record)
      anything_new = record.new_record? || attribute_changed?
   end
  end
end

Solution

  • If you need to check that some attribute was changed, you need to call attribute_changed? method on the record and pass this attribute like this

    return unless record.new_record? || record.attribute_changed?(attribute)
    

    Or may be use metaprogramming method like this

    return unless record.new_record? || record.public_send("#{attribute}_changed?")
    

    Some notes:

    In Ruby we usually use PascalCase for class names and snake_case for hash keys

    Validations are used for data validation, not for some normalization. It is usually used to add validation errors