I’m working on an old, large rails codebase.
Recently, I needed to add a new validation to our users
table, requiring something be entered in the name field.
However, there were many records which didn’t have anything in this field, and that would mean they couldn’t make unrelated changes to their user record (e.g. reset their passwords) as the whole record was invalid.
I have added the following snippet to my ApplicationRecord:
def self.validates_new_and_changed(*fields, opts)
fields.map do |field|
validates field, opts.merge(on: :create)
validates field, opts.merge(if: "#{field}_changed?".to_sym)
end
end
This is short and solves my problem, but I think Rails validations would benefit more generally from having a straightforward way to only run field validations when the field changes.
I’d envisage an API like
validates :name, :encrypted_password, presence: true, on: :create_or_field_changed
This new option for the on
parameter would mean that for existing records, changes to the encrypted_password
field would not generate validation errors on the name
field unless that was also changed.