class ActiveValidation::Internal::Models::Manifest::Installer

Attributes

base_class[R]
checks[R]
context[R]
installed_callbacks[R]

Public Class Methods

new(base_class:, checks: [], context:) click to toggle source
# File lib/active_validation/internal/models/manifest/installer.rb, line 12
def initialize(base_class:, checks: [], context:)
  @base_class = base_class
  @checks = checks
  @context = context
  @installed_callbacks = []
end

Public Instance Methods

callbacks_chain() click to toggle source
# File lib/active_validation/internal/models/manifest/installer.rb, line 51
def callbacks_chain
  base_class._validate_callbacks
end
install() click to toggle source

Add all checks (validations) to base_class

@note we have to use the hack with `callbacks_chain.each.to_a # => chain` since `chain` method is protected.

@return [TrueClass]

# File lib/active_validation/internal/models/manifest/installer.rb, line 26
def install
  @installed_callbacks = chain_mutex.synchronize do
    before = callbacks_chain_elements
    checks.each { |check| base_class.public_send(*check.to_validation_arguments(context: context)) }
    callbacks_chain_elements - before
  end
  true
end
uninstall() click to toggle source

Remove all checks (validations) from base_class

we can not use ActiveSupport provided methods, since we already have our installed callbacks.

@return [FalseClass]

# File lib/active_validation/internal/models/manifest/installer.rb, line 41
def uninstall
  installed_validators = installed_callbacks.map(&:filter).select { |f| f.is_a? ActiveModel::Validator }

  ([base_class] + ActiveSupport::DescendantsTracker.descendants(base_class)).reverse_each do |target|
    uninstall! target: target, installed_validators: installed_validators
  end
  installed_callbacks.clear
  false
end

Private Instance Methods

callbacks_chain_elements() click to toggle source

We cannot call `chain` method directly, so we have to use this hack

@return [Array<ActiveSupport::Callbacks>]

# File lib/active_validation/internal/models/manifest/installer.rb, line 60
def callbacks_chain_elements
  callbacks_chain.each.to_a
end
chain_mutex() click to toggle source

Mutex from ActiveSupport::Callbacks::CallbackChain for `base_class`

@return [Mutex]

# File lib/active_validation/internal/models/manifest/installer.rb, line 67
def chain_mutex
  callbacks_chain.instance_variable_get(:@mutex)
end
uninstall!(target:, installed_validators:) click to toggle source
# File lib/active_validation/internal/models/manifest/installer.rb, line 71
def uninstall!(target:, installed_validators:)
  chain = target._validate_callbacks

  chain.instance_variable_get(:@mutex).synchronize do
    target._validators
          .each_value { |v| v.reject! { |el| installed_validators.include?(el) } }
          .delete_if { |_, v| v.empty?  }

    installed_callbacks.each { |callback| chain.delete(callback) }
  end
end