How can I programmatically copy ActiveModel validators from one model to another?

I am writing a library that will require software copying of validations from one model to another, but I do not understand how to do this.

I have a model that is ActiveModel::Modelwith some validation:

class User < ActiveRecord::Base
  validates :name, presence: true
end

And another model in which I would like to have the same checks:

class UserForm
  include ActiveModel::Model
  attr_accessor :name
end

Now I would like to give UserFormthe same checks as User, and without change User. Copying validators does not work because it ActiveModel::Validationsintercepts callbacks during validation validation:

UserForm._validators = User._validators
UserForm.new.valid?
# => true             # We wanted to see `false` here, but no validations
                      # are actually running because the :validate callback
                      # is empty.

, , , . , , Rails , .

? , ?

+4
1

activerecord/lib/active_record/validations/presence.rb , :

# File activerecord/lib/active_record/validations/presence.rb, line 60
def validates_presence_of(*attr_names)
  validates_with PresenceValidator, _merge_attributes(attr_names)
end

, validates_with alias_method

alias_method :orig_validates_with :validates_with

, - , UserForm

alias_method :orig_validates_with, :validates_with
def validates_with(*args)
  # save the stuff you need, so you can recreate this method call on UserForm
  orig_validates_with(*args)
end

UserForm.validates_with(*saved_attrs). , , /, .

0

Source: https://habr.com/ru/post/1538186/


All Articles