activevalidation 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +32 -9
- data/.overcommit.yml +93 -0
- data/.rspec +1 -1
- data/.rubocop.yml +80 -0
- data/.rubocop_todo.yml +7 -0
- data/.travis.yml +42 -2
- data/.yardops +9 -0
- data/Appraisals +27 -0
- data/Gemfile +24 -1
- data/MIT-LICENSE +20 -0
- data/README.md +142 -20
- data/Rakefile +21 -3
- data/activevalidation.gemspec +35 -25
- data/bin/console +4 -7
- data/gemfiles/am_5.0.gemfile +17 -0
- data/gemfiles/am_5.0.gemfile.lock +159 -0
- data/gemfiles/am_5.1.gemfile +17 -0
- data/gemfiles/am_5.1.gemfile.lock +159 -0
- data/gemfiles/am_5.2.gemfile +17 -0
- data/gemfiles/am_5.2.gemfile.lock +159 -0
- data/gemfiles/am_6.0.gemfile +18 -0
- data/gemfiles/am_6.0.gemfile.lock +158 -0
- data/lib/active_validation.rb +27 -0
- data/lib/active_validation/base_adapter.rb +103 -0
- data/lib/active_validation/configuration.rb +52 -0
- data/lib/active_validation/decorator.rb +27 -0
- data/lib/active_validation/decorators/consistent_registry.rb +36 -0
- data/lib/active_validation/decorators/disallows_duplicates_registry.rb +17 -0
- data/lib/active_validation/errors.rb +28 -0
- data/lib/active_validation/ext/add_active_validation_context_check.rb +21 -0
- data/lib/active_validation/formatters/manifest_name_formatter.rb +13 -0
- data/lib/active_validation/formatters/validation_context_formatter.rb +28 -0
- data/lib/active_validation/frameworks/rspec.rb +10 -0
- data/lib/active_validation/frameworks/rspec/helpers.rb +15 -0
- data/lib/active_validation/internal/models/check.rb +51 -0
- data/lib/active_validation/internal/models/concerns/to_internal.rb +27 -0
- data/lib/active_validation/internal/models/manifest.rb +122 -0
- data/lib/active_validation/internal/models/manifest/installer.rb +86 -0
- data/lib/active_validation/internal/observers/manifest.rb +114 -0
- data/lib/active_validation/model_extension_base.rb +33 -0
- data/lib/active_validation/orm_plugins/active_record_plugin/adapter.rb +59 -0
- data/lib/active_validation/orm_plugins/active_record_plugin/internals/active_validation/internal_model_extensions/check.rb +11 -0
- data/lib/active_validation/orm_plugins/active_record_plugin/model_extension/active_validation/active_record_model_extension.rb +25 -0
- data/lib/active_validation/orm_plugins/active_record_plugin/models/active_validation/check.rb +31 -0
- data/lib/active_validation/orm_plugins/active_record_plugin/models/active_validation/check/concerns/method_must_be_allowed.rb +38 -0
- data/lib/active_validation/orm_plugins/active_record_plugin/models/active_validation/check/validate_method.rb +9 -0
- data/lib/active_validation/orm_plugins/active_record_plugin/models/active_validation/check/validates_method.rb +9 -0
- data/lib/active_validation/orm_plugins/active_record_plugin/models/active_validation/check/validates_with_method.rb +19 -0
- data/lib/active_validation/orm_plugins/active_record_plugin/models/active_validation/concerns/protect_from_mutable_instance_methods.rb +31 -0
- data/lib/active_validation/orm_plugins/active_record_plugin/models/active_validation/manifest.rb +21 -0
- data/lib/active_validation/orm_plugins/active_record_plugin/types/active_validation/type/version.rb +17 -0
- data/lib/active_validation/registry.rb +55 -0
- data/lib/active_validation/values/base.rb +39 -0
- data/lib/active_validation/values/method_name.rb +22 -0
- data/lib/active_validation/values/version.rb +17 -0
- data/lib/active_validation/verifier.rb +150 -0
- data/lib/active_validation/version.rb +5 -0
- data/spec/active_validation/base_adapter_spec.rb +23 -0
- data/spec/active_validation/configuration_spec.rb +52 -0
- data/spec/active_validation/decorators/consistent_registry_spec.rb +117 -0
- data/spec/active_validation/decorators/disallows_duplicates_registry_spec.rb +21 -0
- data/spec/active_validation/formatters/manifest_name_formatter_spec.rb +7 -0
- data/spec/active_validation/formatters/validation_context_formatter_spec.rb +39 -0
- data/spec/active_validation/internal/models/check_spec.rb +67 -0
- data/spec/active_validation/internal/models/manifest/installer_spec.rb +177 -0
- data/spec/active_validation/internal/models/manifest_spec.rb +136 -0
- data/spec/active_validation/internal/observers/manifest_spec.rb +201 -0
- data/spec/active_validation/model_extension_base_spec.rb +71 -0
- data/spec/active_validation/orm_plugins/active_record_plugin/adapter_spec.rb +31 -0
- data/spec/active_validation/orm_plugins/active_record_plugin/adapter_spec_orm_specific_spec.rb +84 -0
- data/spec/active_validation/orm_plugins/active_record_plugin/models/active_validation/check/validate_method_spec.rb +26 -0
- data/spec/active_validation/orm_plugins/active_record_plugin/models/active_validation/check/validates_method_spec.rb +26 -0
- data/spec/active_validation/orm_plugins/active_record_plugin/models/active_validation/check/validates_with_method_spec.rb +34 -0
- data/spec/active_validation/orm_plugins/active_record_plugin/models/active_validation/check_spec.rb +48 -0
- data/spec/active_validation/orm_plugins/active_record_plugin/models/active_validation/manifest_spec.rb +61 -0
- data/spec/active_validation/orm_plugins/active_record_plugin/readme_spec.rb +89 -0
- data/spec/active_validation/registry_spec.rb +76 -0
- data/spec/active_validation/values/base_spec.rb +61 -0
- data/spec/active_validation/values/method_name_spec.rb +16 -0
- data/spec/active_validation/values/version_spec.rb +36 -0
- data/spec/active_validation/verifier_spec.rb +214 -0
- data/spec/active_validation_spec.rb +19 -0
- data/spec/factories/internal/internal_check.rb +43 -0
- data/spec/features/active_record/child_record.feature +32 -0
- data/spec/features/active_record/new_record.feature +22 -0
- data/spec/features/no_orm/install.feature +19 -0
- data/spec/features/no_orm/validate.feature +27 -0
- data/spec/features/no_orm/validate_with_multiple_manifests.feature +29 -0
- data/spec/features/no_orm/validate_with_multiple_versions.feature +42 -0
- data/spec/features/placeholders/be_matcher.rb +7 -0
- data/spec/features/placeholders/klass.rb +5 -0
- data/spec/features/placeholders/version.rb +11 -0
- data/spec/features/placeholders/whether_to.rb +11 -0
- data/spec/features/step_definitions/active_record_steps.rb +7 -0
- data/spec/features/step_definitions/steps.rb +85 -0
- data/spec/orm/active_record/db_adapters/database.mysql.yml +12 -0
- data/spec/orm/active_record/db_adapters/database.postgres.yml +11 -0
- data/spec/orm/active_record/db_adapters/database.sqlite.yml +8 -0
- data/spec/orm/active_record/factories/check/check_validate.rb +8 -0
- data/spec/orm/active_record/factories/check/check_validates.rb +8 -0
- data/spec/orm/active_record/factories/check/check_validates_with.rb +19 -0
- data/spec/orm/active_record/factories/manifest.rb +29 -0
- data/spec/orm/active_record/prepare_db.rb +89 -0
- data/spec/orm/active_record/setup.rb +11 -0
- data/spec/orm/mongoid/setup.rb +15 -0
- data/spec/spec_helper.rb +38 -0
- data/spec/support/database_cleaner.rb +16 -0
- data/spec/support/deferred_garbage_collection.rb +31 -0
- data/spec/support/define_constant_macros.rb +17 -0
- data/spec/support/factory_bot.rb +12 -0
- data/spec/support/helpers.rb +3 -0
- data/spec/support/helpers/only_with_active_record.rb +15 -0
- data/spec/support/matchers/delegate.rb +50 -0
- data/spec/support/matchers/have_attr.rb +58 -0
- data/spec/support/mongoid.yml +6 -0
- data/spec/support/shared_examples/check_attributes.rb +9 -0
- data/spec/support/shared_examples/verifiers_registry.rb +10 -0
- data/spec/support/simplecov.rb +11 -0
- data/spec/turnip_helper.rb +4 -0
- metadata +304 -20
- data/lib/activevalidation.rb +0 -6
- data/lib/activevalidation/version.rb +0 -3
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveValidation
|
|
4
|
+
class Configuration
|
|
5
|
+
attr_reader :verifiers_registry, :orm_adapters_registry, :method_name_values_registry
|
|
6
|
+
|
|
7
|
+
def initialize
|
|
8
|
+
@orm_adapters_registry = Registry.new("Orm adapters")
|
|
9
|
+
@verifiers_registry = strict_registry name: "Verifiers", klass: Verifier
|
|
10
|
+
@method_name_values_registry = strict_registry name: "Validation methods", klass: Values::MethodName
|
|
11
|
+
|
|
12
|
+
@manifest_name_formatter = Formatters::ManifestNameFormatter
|
|
13
|
+
@validation_context_formatter = Formatters::ValidationContextFormatter
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
attr_accessor :manifest_name_formatter, :validation_context_formatter
|
|
17
|
+
|
|
18
|
+
attr_reader :orm_adapter
|
|
19
|
+
|
|
20
|
+
def orm_adapter=(name, retry_attempt: 0)
|
|
21
|
+
retry_attempt += 1
|
|
22
|
+
@orm_adapter = case name
|
|
23
|
+
when BaseAdapter
|
|
24
|
+
name
|
|
25
|
+
when Class
|
|
26
|
+
name.new
|
|
27
|
+
when String, Symbol
|
|
28
|
+
"ActiveValidation::OrmPlugins::#{name.to_s.classify}Plugin::Adapter".constantize.new
|
|
29
|
+
else
|
|
30
|
+
raise ArgumentError "ORM plugin not found"
|
|
31
|
+
end
|
|
32
|
+
rescue NameError
|
|
33
|
+
raise if retry_attempt > 1
|
|
34
|
+
|
|
35
|
+
require_relative "orm_plugins/#{name}_plugin/adapter"
|
|
36
|
+
retry
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def verifier_defaults(&block)
|
|
40
|
+
@verifier_defaults ||= ->(_config) {}
|
|
41
|
+
return @verifier_defaults unless block_given?
|
|
42
|
+
|
|
43
|
+
@verifier_defaults = block
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def strict_registry(name:, klass:)
|
|
49
|
+
Decorators::ConsistentRegistry.new(klass, Decorators::DisallowsDuplicatesRegistry.new(Registry.new(name)))
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveValidation
|
|
4
|
+
class Decorator < BasicObject
|
|
5
|
+
undef_method :==
|
|
6
|
+
|
|
7
|
+
def initialize(component)
|
|
8
|
+
@component = component
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def method_missing(name, *args, &block) # rubocop:disable Style/MethodMissingSuper
|
|
12
|
+
@component.send(name, *args, &block)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def respond_to_missing?(name, include_private = false)
|
|
16
|
+
@component.respond_to?(name, true) || super
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def send(symbol, *args, &block)
|
|
20
|
+
__send__(symbol, *args, &block)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.const_missing(name)
|
|
24
|
+
::Object.const_get(name)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveValidation
|
|
4
|
+
module Decorators
|
|
5
|
+
class ConsistentRegistry < Decorator
|
|
6
|
+
# All items in the registry must be ancestors of this Class
|
|
7
|
+
# @return [Class]
|
|
8
|
+
attr_reader :klass
|
|
9
|
+
|
|
10
|
+
def initialize(klass, registry)
|
|
11
|
+
super registry
|
|
12
|
+
|
|
13
|
+
@klass = klass.is_a?(Class) ? klass : klass.to_s.constantize
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def find_or_build(name, &block)
|
|
17
|
+
return klass.new(name, &block) unless registered?(name)
|
|
18
|
+
|
|
19
|
+
found = find(name)
|
|
20
|
+
found.instance_exec(found, &block) if block
|
|
21
|
+
found
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def find_or_add(name, &block)
|
|
25
|
+
record = find_or_build(name, &block)
|
|
26
|
+
registered?(name) ? record : register(name, record)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def register(name, item)
|
|
30
|
+
raise Errors::InconsistentRegistryError unless item.is_a? klass
|
|
31
|
+
|
|
32
|
+
super
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveValidation
|
|
4
|
+
module Decorators
|
|
5
|
+
class DisallowsDuplicatesRegistry < Decorator
|
|
6
|
+
def register(name, item)
|
|
7
|
+
return @component.register(name, item) unless registered?(name)
|
|
8
|
+
|
|
9
|
+
raise Errors::DuplicateRegistryEntryError, "#{@component.name} already registered: #{name}"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def ==(other)
|
|
13
|
+
object_id == other.object_id
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveValidation
|
|
4
|
+
module Errors
|
|
5
|
+
class ImmutableError < StandardError
|
|
6
|
+
def initialize(msg = "Object can not be changed in lifetime")
|
|
7
|
+
super
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class DuplicateRegistryEntryError < RuntimeError; end
|
|
12
|
+
|
|
13
|
+
class InconsistentRegistryError < ArgumentError; end
|
|
14
|
+
|
|
15
|
+
class UnsupportedMethodError < ArgumentError
|
|
16
|
+
attr_reader :value, :allowed_methods
|
|
17
|
+
def initialize(value:, allowed_methods:)
|
|
18
|
+
super
|
|
19
|
+
@value = value
|
|
20
|
+
@allowed_methods = allowed_methods
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def to_s
|
|
24
|
+
"You provided #{value.inspect} while supported are only #{allowed_methods.inspect}"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveValidation
|
|
4
|
+
module Ext
|
|
5
|
+
module AddActiveValidationContextCheck
|
|
6
|
+
def valid?(*_args)
|
|
7
|
+
result = super
|
|
8
|
+
return result unless ActiveValidation.config.verifiers_registry.registered?(self.class)
|
|
9
|
+
|
|
10
|
+
av_context = try(:manifest).try(:context) ||
|
|
11
|
+
ActiveValidation.config.verifiers_registry[self.class].current_manifest.try(:context)
|
|
12
|
+
return result unless av_context
|
|
13
|
+
|
|
14
|
+
self.validation_context = av_context
|
|
15
|
+
run_validations!
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
alias validate valid?
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveValidation
|
|
4
|
+
module Formatters
|
|
5
|
+
class ValidationContextFormatter
|
|
6
|
+
class << self
|
|
7
|
+
def call(*args)
|
|
8
|
+
new(*args).call
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def initialize(manifest)
|
|
13
|
+
@manifest = manifest
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
attr_reader :manifest
|
|
17
|
+
|
|
18
|
+
delegate :options, :id, :name, to: :manifest
|
|
19
|
+
|
|
20
|
+
def call
|
|
21
|
+
["active_validation", "id#{id}"].tap do |base|
|
|
22
|
+
base << "on_#{options[:on]}" if options[:on]
|
|
23
|
+
base << name.to_s.underscore unless name.blank?
|
|
24
|
+
end.join("_")
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rspec/core"
|
|
4
|
+
require "rspec/matchers"
|
|
5
|
+
require "active_validation/frameworks/rspec/helpers"
|
|
6
|
+
|
|
7
|
+
RSpec.configure do |config|
|
|
8
|
+
config.include ::ActiveValidation::RSpec::Helpers::InstanceMethods
|
|
9
|
+
config.extend ::ActiveValidation::RSpec::Helpers::ClassMethods
|
|
10
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveValidation
|
|
4
|
+
module RSpec
|
|
5
|
+
module Helpers
|
|
6
|
+
# Included in the RSpec configuration in `frameworks/rspec.rb`
|
|
7
|
+
module InstanceMethods
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Extended by the RSpec configuration in `frameworks/rspec.rb`
|
|
11
|
+
module ClassMethods
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveValidation
|
|
4
|
+
module Internal
|
|
5
|
+
module Models
|
|
6
|
+
class Check
|
|
7
|
+
attr_reader :method_name, :argument, :options, :created_at
|
|
8
|
+
def initialize(method_name:, argument:, options: {}, created_at: nil, **_other)
|
|
9
|
+
@method_name = registry.find_or_add method_name
|
|
10
|
+
@argument = argument
|
|
11
|
+
@options = options.to_h.deep_symbolize_keys
|
|
12
|
+
@created_at = created_at
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def ==(other)
|
|
16
|
+
method_name == other.method_name &&
|
|
17
|
+
argument == other.argument &&
|
|
18
|
+
options == other.options
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def to_hash
|
|
22
|
+
as_json
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def as_json(only: %i[method_name argument options], **_options)
|
|
26
|
+
only.each_with_object({}) { |el, acc| acc[el.to_sym] = public_send(el).as_json }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def to_internal_check
|
|
30
|
+
self
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def normalized_argument
|
|
34
|
+
method_name.to_sym == :validates_with ? argument.to_s.constantize : argument.to_sym
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def to_validation_arguments(context: nil)
|
|
38
|
+
[method_name.to_sym,
|
|
39
|
+
normalized_argument,
|
|
40
|
+
options.merge(on: context) { |_, old, new| Array(new) + Array(old) }]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def registry
|
|
46
|
+
ActiveValidation.config.method_name_values_registry
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveValidation
|
|
4
|
+
module Internal
|
|
5
|
+
module Models
|
|
6
|
+
module Concerns
|
|
7
|
+
module ToInternal
|
|
8
|
+
module Check
|
|
9
|
+
refine Hash do
|
|
10
|
+
def to_internal_check
|
|
11
|
+
ActiveValidation::Internal::Models::Check.new to_options!
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
module Manifest
|
|
17
|
+
refine Hash do
|
|
18
|
+
def to_internal_manifest
|
|
19
|
+
ActiveValidation::Internal::Models::Manifest.new to_options!
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
using ActiveValidation::Internal::Models::Concerns::ToInternal::Check
|
|
4
|
+
|
|
5
|
+
module ActiveValidation
|
|
6
|
+
module Internal
|
|
7
|
+
module Models
|
|
8
|
+
class Manifest
|
|
9
|
+
attr_reader :version, :base_klass, :created_at, :checks, :options, :other, :id, :name
|
|
10
|
+
|
|
11
|
+
delegate :installed_callbacks, to: :installer
|
|
12
|
+
|
|
13
|
+
# @param [Hash] Manifest options hash
|
|
14
|
+
# @option manifest_hash [String] :name Human readable name, by default build with selected
|
|
15
|
+
# formatter for current manifest
|
|
16
|
+
# @option manifest_hash [String, #to_s] :base_klass (base_klass) Base klass for the Manifest
|
|
17
|
+
# @option manifest_hash [String, Symbol, Integer, Values::Version] :version (:current) Version
|
|
18
|
+
# of the current manifest
|
|
19
|
+
# @option manifest_hash [Internal::Check] :checks ([])
|
|
20
|
+
#
|
|
21
|
+
# @example Add new manifest:
|
|
22
|
+
# new({ name: 'Cool Manifest',
|
|
23
|
+
# version: 42,
|
|
24
|
+
# base_klass: 'Bar',
|
|
25
|
+
# checks: [
|
|
26
|
+
# { method_name: "validates", argument: "name", options: { presence: true } }
|
|
27
|
+
# ]})
|
|
28
|
+
def initialize(version:, base_klass:, checks: [], options: {}, **other)
|
|
29
|
+
@version = ActiveValidation::Values::Version.new version
|
|
30
|
+
@base_klass = base_klass.to_s
|
|
31
|
+
@checks = Array(checks).map(&:to_internal_check)
|
|
32
|
+
@other = ActiveSupport::OrderedOptions.new other
|
|
33
|
+
|
|
34
|
+
@id = other[:id]
|
|
35
|
+
@name = other[:name]
|
|
36
|
+
@created_at = other[:created_at]
|
|
37
|
+
@options = options.to_h.to_options!
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def ==(other)
|
|
41
|
+
return true if id == other.id
|
|
42
|
+
|
|
43
|
+
version == other.version &&
|
|
44
|
+
base_klass == other.base_klass &&
|
|
45
|
+
options == other.options &&
|
|
46
|
+
checks == other.checks
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def base_class
|
|
50
|
+
base_klass.constantize
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def to_hash
|
|
54
|
+
as_json
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# rubocop:disable Naming/MemoizedInstanceVariableName
|
|
58
|
+
def install
|
|
59
|
+
@installed ||= installer.install
|
|
60
|
+
end
|
|
61
|
+
# rubocop:enable Naming/MemoizedInstanceVariableName
|
|
62
|
+
|
|
63
|
+
def uninstall
|
|
64
|
+
return false unless installed?
|
|
65
|
+
|
|
66
|
+
@installed = installer.uninstall
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Are the callbacks installed to the `base_class`?
|
|
70
|
+
#
|
|
71
|
+
# @return [TrueClass, FalseClass]
|
|
72
|
+
def installed?
|
|
73
|
+
!!@installed
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# ActiveSupport#as_json interface
|
|
77
|
+
# Supported options:
|
|
78
|
+
# :only [Array<Symbol>, Symbol] select only listed elements
|
|
79
|
+
#
|
|
80
|
+
# Nested elements accept options:
|
|
81
|
+
# :only [Array<Symbol>, Symbol] select only listed elements
|
|
82
|
+
# :as [Symbol, String] in place rename for the column
|
|
83
|
+
#
|
|
84
|
+
# @example
|
|
85
|
+
# as_json(only: :version, checks: { as: :checks_attributes,
|
|
86
|
+
# only: [:argument] })
|
|
87
|
+
#
|
|
88
|
+
# @return [Hash]
|
|
89
|
+
def as_json(only: %i[version base_klass checks name id], **options)
|
|
90
|
+
only = Array(only)
|
|
91
|
+
{}.tap do |acc|
|
|
92
|
+
options.each_pair do |k, v|
|
|
93
|
+
only.delete(k)
|
|
94
|
+
as = v.delete(:as)
|
|
95
|
+
key_name = (as || k).to_sym
|
|
96
|
+
acc[key_name] = public_send(k).as_json(v)
|
|
97
|
+
end
|
|
98
|
+
only.each { |el| acc[el.to_sym] = public_send(el).as_json }
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def to_internal_manifest
|
|
103
|
+
self
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Formatted context, as it will be stored on `on` option with the
|
|
107
|
+
# validations
|
|
108
|
+
#
|
|
109
|
+
# @return [String]
|
|
110
|
+
def context
|
|
111
|
+
@context ||= ActiveValidation.config.validation_context_formatter.call self
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
private
|
|
115
|
+
|
|
116
|
+
def installer
|
|
117
|
+
@installer ||= Installer.new(base_class: base_class, checks: checks, context: context)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|