activeentity 0.0.1.beta1
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 +7 -0
- data/MIT-LICENSE +42 -0
- data/README.md +145 -0
- data/Rakefile +29 -0
- data/lib/active_entity.rb +73 -0
- data/lib/active_entity/aggregations.rb +276 -0
- data/lib/active_entity/associations.rb +146 -0
- data/lib/active_entity/associations/embedded/association.rb +134 -0
- data/lib/active_entity/associations/embedded/builder/association.rb +100 -0
- data/lib/active_entity/associations/embedded/builder/collection_association.rb +69 -0
- data/lib/active_entity/associations/embedded/builder/embedded_in.rb +38 -0
- data/lib/active_entity/associations/embedded/builder/embeds_many.rb +13 -0
- data/lib/active_entity/associations/embedded/builder/embeds_one.rb +16 -0
- data/lib/active_entity/associations/embedded/builder/singular_association.rb +28 -0
- data/lib/active_entity/associations/embedded/collection_association.rb +188 -0
- data/lib/active_entity/associations/embedded/collection_proxy.rb +310 -0
- data/lib/active_entity/associations/embedded/embedded_in_association.rb +31 -0
- data/lib/active_entity/associations/embedded/embeds_many_association.rb +15 -0
- data/lib/active_entity/associations/embedded/embeds_one_association.rb +19 -0
- data/lib/active_entity/associations/embedded/singular_association.rb +35 -0
- data/lib/active_entity/attribute_assignment.rb +85 -0
- data/lib/active_entity/attribute_decorators.rb +90 -0
- data/lib/active_entity/attribute_methods.rb +330 -0
- data/lib/active_entity/attribute_methods/before_type_cast.rb +78 -0
- data/lib/active_entity/attribute_methods/primary_key.rb +98 -0
- data/lib/active_entity/attribute_methods/query.rb +35 -0
- data/lib/active_entity/attribute_methods/read.rb +47 -0
- data/lib/active_entity/attribute_methods/serialization.rb +90 -0
- data/lib/active_entity/attribute_methods/time_zone_conversion.rb +91 -0
- data/lib/active_entity/attribute_methods/write.rb +63 -0
- data/lib/active_entity/attributes.rb +165 -0
- data/lib/active_entity/base.rb +303 -0
- data/lib/active_entity/coders/json.rb +15 -0
- data/lib/active_entity/coders/yaml_column.rb +50 -0
- data/lib/active_entity/core.rb +281 -0
- data/lib/active_entity/define_callbacks.rb +17 -0
- data/lib/active_entity/enum.rb +234 -0
- data/lib/active_entity/errors.rb +80 -0
- data/lib/active_entity/gem_version.rb +17 -0
- data/lib/active_entity/inheritance.rb +278 -0
- data/lib/active_entity/integration.rb +78 -0
- data/lib/active_entity/locale/en.yml +45 -0
- data/lib/active_entity/model_schema.rb +115 -0
- data/lib/active_entity/nested_attributes.rb +592 -0
- data/lib/active_entity/readonly_attributes.rb +47 -0
- data/lib/active_entity/reflection.rb +441 -0
- data/lib/active_entity/serialization.rb +25 -0
- data/lib/active_entity/store.rb +242 -0
- data/lib/active_entity/translation.rb +24 -0
- data/lib/active_entity/type.rb +73 -0
- data/lib/active_entity/type/date.rb +9 -0
- data/lib/active_entity/type/date_time.rb +9 -0
- data/lib/active_entity/type/decimal_without_scale.rb +15 -0
- data/lib/active_entity/type/hash_lookup_type_map.rb +25 -0
- data/lib/active_entity/type/internal/timezone.rb +17 -0
- data/lib/active_entity/type/json.rb +30 -0
- data/lib/active_entity/type/modifiers/array.rb +72 -0
- data/lib/active_entity/type/registry.rb +92 -0
- data/lib/active_entity/type/serialized.rb +71 -0
- data/lib/active_entity/type/text.rb +11 -0
- data/lib/active_entity/type/time.rb +21 -0
- data/lib/active_entity/type/type_map.rb +62 -0
- data/lib/active_entity/type/unsigned_integer.rb +17 -0
- data/lib/active_entity/validate_embedded_association.rb +305 -0
- data/lib/active_entity/validations.rb +50 -0
- data/lib/active_entity/validations/absence.rb +25 -0
- data/lib/active_entity/validations/associated.rb +60 -0
- data/lib/active_entity/validations/length.rb +26 -0
- data/lib/active_entity/validations/presence.rb +68 -0
- data/lib/active_entity/validations/subset.rb +76 -0
- data/lib/active_entity/validations/uniqueness_in_embedding.rb +99 -0
- data/lib/active_entity/version.rb +10 -0
- data/lib/tasks/active_entity_tasks.rake +6 -0
- metadata +155 -0
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveEntity
|
4
|
+
# = Active Entity \Validations
|
5
|
+
#
|
6
|
+
# Active Entity includes the majority of its validations from ActiveModel::Validations
|
7
|
+
# all of which accept the <tt>:on</tt> argument to define the context where the
|
8
|
+
# validations are active. Active Entity will always supply either the context of
|
9
|
+
# <tt>:create</tt> or <tt>:update</tt> dependent on whether the model is a
|
10
|
+
# {new_record?}[rdoc-ref:Persistence#new_record?].
|
11
|
+
module Validations
|
12
|
+
extend ActiveSupport::Concern
|
13
|
+
include ActiveModel::Validations
|
14
|
+
|
15
|
+
# Runs all the validations within the specified context. Returns +true+ if
|
16
|
+
# no errors are found, +false+ otherwise.
|
17
|
+
#
|
18
|
+
# Aliased as #validate.
|
19
|
+
#
|
20
|
+
# If the argument is +false+ (default is +nil+), the context is set to <tt>:create</tt> if
|
21
|
+
# {new_record?}[rdoc-ref:Persistence#new_record?] is +true+, and to <tt>:update</tt> if it is not.
|
22
|
+
#
|
23
|
+
# \Validations with no <tt>:on</tt> option will run no matter the context. \Validations with
|
24
|
+
# some <tt>:on</tt> option will only run in the specified context.
|
25
|
+
def valid?(context = nil)
|
26
|
+
context ||= default_validation_context
|
27
|
+
output = super(context)
|
28
|
+
errors.empty? && output
|
29
|
+
end
|
30
|
+
|
31
|
+
alias_method :validate, :valid?
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def default_validation_context
|
36
|
+
:default
|
37
|
+
end
|
38
|
+
|
39
|
+
def perform_validations(options = {})
|
40
|
+
options[:validate] == false || valid?(options[:context])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
require "active_entity/validations/associated"
|
46
|
+
require "active_entity/validations/presence"
|
47
|
+
require "active_entity/validations/absence"
|
48
|
+
require "active_entity/validations/length"
|
49
|
+
require "active_entity/validations/subset"
|
50
|
+
require "active_entity/validations/uniqueness_in_embedding"
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveEntity
|
4
|
+
module Validations
|
5
|
+
class AbsenceValidator < ActiveModel::Validations::AbsenceValidator # :nodoc:
|
6
|
+
def validate_each(record, attribute, association_or_value)
|
7
|
+
if record.class._reflect_on_association(attribute)
|
8
|
+
association_or_value = Array.wrap(association_or_value).reject(&:marked_for_destruction?)
|
9
|
+
end
|
10
|
+
super
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
# Validates that the specified attributes are not present (as defined by
|
16
|
+
# Object#present?). If the attribute is an association, the associated object
|
17
|
+
# is considered absent if it was marked for destruction.
|
18
|
+
#
|
19
|
+
# See ActiveModel::Validations::HelperMethods.validates_absence_of for more information.
|
20
|
+
def validates_absence_of(*attr_names)
|
21
|
+
validates_with AbsenceValidator, _merge_attributes(attr_names)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveEntity
|
4
|
+
module Validations
|
5
|
+
class AssociatedValidator < ActiveModel::EachValidator #:nodoc:
|
6
|
+
def validate_each(record, attribute, value)
|
7
|
+
if Array(value).reject { |r| valid_object?(r) }.any?
|
8
|
+
record.errors.add(attribute, :invalid, options.merge(value: value))
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def valid_object?(record)
|
15
|
+
(record.respond_to?(:marked_for_destruction?) && record.marked_for_destruction?) || record.valid?
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
# Validates whether the associated object or objects are all valid.
|
21
|
+
# Works with any kind of association.
|
22
|
+
#
|
23
|
+
# class Book < ActiveEntity::Base
|
24
|
+
# has_many :pages
|
25
|
+
# belongs_to :library
|
26
|
+
#
|
27
|
+
# validates_associated :pages, :library
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# WARNING: This validation must not be used on both ends of an association.
|
31
|
+
# Doing so will lead to a circular dependency and cause infinite recursion.
|
32
|
+
#
|
33
|
+
# NOTE: This validation will not fail if the association hasn't been
|
34
|
+
# assigned. If you want to ensure that the association is both present and
|
35
|
+
# guaranteed to be valid, you also need to use
|
36
|
+
# {validates_presence_of}[rdoc-ref:Validations::ClassMethods#validates_presence_of].
|
37
|
+
#
|
38
|
+
# Configuration options:
|
39
|
+
#
|
40
|
+
# * <tt>:message</tt> - A custom error message (default is: "is invalid").
|
41
|
+
# * <tt>:on</tt> - Specifies the contexts where this validation is active.
|
42
|
+
# Runs in all validation contexts by default +nil+. You can pass a symbol
|
43
|
+
# or an array of symbols. (e.g. <tt>on: :create</tt> or
|
44
|
+
# <tt>on: :custom_validation_context</tt> or
|
45
|
+
# <tt>on: [:create, :custom_validation_context]</tt>)
|
46
|
+
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine
|
47
|
+
# if the validation should occur (e.g. <tt>if: :allow_validation</tt>,
|
48
|
+
# or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method,
|
49
|
+
# proc or string should return or evaluate to a +true+ or +false+ value.
|
50
|
+
# * <tt>:unless</tt> - Specifies a method, proc or string to call to
|
51
|
+
# determine if the validation should not occur (e.g. <tt>unless: :skip_validation</tt>,
|
52
|
+
# or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>). The
|
53
|
+
# method, proc or string should return or evaluate to a +true+ or +false+
|
54
|
+
# value.
|
55
|
+
def validates_associated(*attr_names)
|
56
|
+
validates_with AssociatedValidator, _merge_attributes(attr_names)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveEntity
|
4
|
+
module Validations
|
5
|
+
class LengthValidator < ActiveModel::Validations::LengthValidator # :nodoc:
|
6
|
+
def validate_each(record, attribute, association_or_value)
|
7
|
+
if association_or_value.respond_to?(:loaded?) && association_or_value.loaded?
|
8
|
+
association_or_value = association_or_value.target.reject(&:marked_for_destruction?)
|
9
|
+
end
|
10
|
+
super
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
# Validates that the specified attributes match the length restrictions supplied.
|
16
|
+
# If the attribute is an association, records that are marked for destruction are not counted.
|
17
|
+
#
|
18
|
+
# See ActiveModel::Validations::HelperMethods.validates_length_of for more information.
|
19
|
+
def validates_length_of(*attr_names)
|
20
|
+
validates_with LengthValidator, _merge_attributes(attr_names)
|
21
|
+
end
|
22
|
+
|
23
|
+
alias_method :validates_size_of, :validates_length_of
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveEntity
|
4
|
+
module Validations
|
5
|
+
class PresenceValidator < ActiveModel::Validations::PresenceValidator # :nodoc:
|
6
|
+
def validate_each(record, attribute, association_or_value)
|
7
|
+
if record.class._reflect_on_association(attribute)
|
8
|
+
association_or_value = Array.wrap(association_or_value).reject(&:marked_for_destruction?)
|
9
|
+
end
|
10
|
+
super
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
# Validates that the specified attributes are not blank (as defined by
|
16
|
+
# Object#blank?), and, if the attribute is an association, that the
|
17
|
+
# associated object is not marked for destruction. Happens by default
|
18
|
+
# on save.
|
19
|
+
#
|
20
|
+
# class Person < ActiveEntity::Base
|
21
|
+
# has_one :face
|
22
|
+
# validates_presence_of :face
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# The face attribute must be in the object and it cannot be blank or marked
|
26
|
+
# for destruction.
|
27
|
+
#
|
28
|
+
# If you want to validate the presence of a boolean field (where the real values
|
29
|
+
# are true and false), you will want to use
|
30
|
+
# <tt>validates_inclusion_of :field_name, in: [true, false]</tt>.
|
31
|
+
#
|
32
|
+
# This is due to the way Object#blank? handles boolean values:
|
33
|
+
# <tt>false.blank? # => true</tt>.
|
34
|
+
#
|
35
|
+
# This validator defers to the Active Model validation for presence, adding the
|
36
|
+
# check to see that an associated object is not marked for destruction. This
|
37
|
+
# prevents the parent object from validating successfully and saving, which then
|
38
|
+
# deletes the associated object, thus putting the parent object into an invalid
|
39
|
+
# state.
|
40
|
+
#
|
41
|
+
# NOTE: This validation will not fail while using it with an association
|
42
|
+
# if the latter was assigned but not valid. If you want to ensure that
|
43
|
+
# it is both present and valid, you also need to use
|
44
|
+
# {validates_associated}[rdoc-ref:Validations::ClassMethods#validates_associated].
|
45
|
+
#
|
46
|
+
# Configuration options:
|
47
|
+
# * <tt>:message</tt> - A custom error message (default is: "can't be blank").
|
48
|
+
# * <tt>:on</tt> - Specifies the contexts where this validation is active.
|
49
|
+
# Runs in all validation contexts by default +nil+. You can pass a symbol
|
50
|
+
# or an array of symbols. (e.g. <tt>on: :create</tt> or
|
51
|
+
# <tt>on: :custom_validation_context</tt> or
|
52
|
+
# <tt>on: [:create, :custom_validation_context]</tt>)
|
53
|
+
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine if
|
54
|
+
# the validation should occur (e.g. <tt>if: :allow_validation</tt>, or
|
55
|
+
# <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method, proc
|
56
|
+
# or string should return or evaluate to a +true+ or +false+ value.
|
57
|
+
# * <tt>:unless</tt> - Specifies a method, proc or string to call to determine
|
58
|
+
# if the validation should not occur (e.g. <tt>unless: :skip_validation</tt>,
|
59
|
+
# or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>). The method,
|
60
|
+
# proc or string should return or evaluate to a +true+ or +false+ value.
|
61
|
+
# * <tt>:strict</tt> - Specifies whether validation should be strict.
|
62
|
+
# See ActiveModel::Validations#validates! for more information.
|
63
|
+
def validates_presence_of(*attr_names)
|
64
|
+
validates_with PresenceValidator, _merge_attributes(attr_names)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveEntity
|
4
|
+
module Validations
|
5
|
+
class SubsetValidator < ActiveModel::EachValidator # :nodoc:
|
6
|
+
ERROR_MESSAGE = "An object with the method #include? or a proc, lambda or symbol is required, " \
|
7
|
+
"and must be supplied as the :in (or :within) option of the configuration hash"
|
8
|
+
|
9
|
+
def check_validity!
|
10
|
+
unless delimiter.respond_to?(:include?) || delimiter.respond_to?(:call) || delimiter.respond_to?(:to_sym)
|
11
|
+
raise ArgumentError, ERROR_MESSAGE
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def validate_each(record, attribute, value)
|
16
|
+
if value && !value.respond_to?(:to_a)
|
17
|
+
raise ArgumentError, "#{record} can't respond `to_a`."
|
18
|
+
end
|
19
|
+
|
20
|
+
unless subset?(record, value)
|
21
|
+
record.errors.add(attribute, :non_subset, options.except(:in, :within).merge!(value: value))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def delimiter
|
28
|
+
@delimiter ||= options[:in] || options[:within]
|
29
|
+
end
|
30
|
+
|
31
|
+
def subset?(record, value)
|
32
|
+
enumerable = value.to_a
|
33
|
+
members =
|
34
|
+
if delimiter.respond_to?(:call)
|
35
|
+
delimiter.call(record)
|
36
|
+
elsif delimiter.respond_to?(:to_sym)
|
37
|
+
record.send(delimiter)
|
38
|
+
else
|
39
|
+
delimiter
|
40
|
+
end
|
41
|
+
|
42
|
+
(members & enumerable).size == enumerable.size
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
module ClassMethods
|
47
|
+
# Validates whether the value of the specified attribute is available in a
|
48
|
+
# particular enumerable object.
|
49
|
+
#
|
50
|
+
# class Person < ActiveRecord::Base
|
51
|
+
# validates :tags, subset: %w( m f )
|
52
|
+
# validates_subset_of :tags, in: %w( m f )
|
53
|
+
# validates_inclusion_of :tags, in: %w( m f ), message: "tag %{value} is not included in the list"
|
54
|
+
# validates_inclusion_of :tags, in: ->(record) { record.available_tags }
|
55
|
+
# validates_inclusion_of :tags, in: :available_tags
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# Configuration options:
|
59
|
+
# * <tt>:in</tt> - An enumerable object of available items. This can be
|
60
|
+
# supplied as a proc, lambda or symbol which returns an enumerable. If the
|
61
|
+
# enumerable is a numerical, time or datetime range the test is performed
|
62
|
+
# with <tt>Range#cover?</tt>, otherwise with <tt>include?</tt>. When using
|
63
|
+
# a proc or lambda the instance under validation is passed as an argument.
|
64
|
+
# * <tt>:within</tt> - A synonym(or alias) for <tt>:in</tt>
|
65
|
+
# * <tt>:message</tt> - Specifies a custom error message (default is: "is
|
66
|
+
# not included in the list").
|
67
|
+
#
|
68
|
+
# There is also a list of default options supported by every validator:
|
69
|
+
# +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+.
|
70
|
+
# See <tt>ActiveModel::Validations#validates</tt> for more information
|
71
|
+
def validates_subset_of(*attr_names)
|
72
|
+
validates_with SubsetValidator, _merge_attributes(attr_names)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveEntity
|
4
|
+
module Validations
|
5
|
+
class UniquenessInEmbeddingValidator < ActiveModel::EachValidator # :nodoc:
|
6
|
+
ERROR_MESSAGE = "`key` option of the configuration hash must be symbol or array of symbols."
|
7
|
+
|
8
|
+
def check_validity!
|
9
|
+
return if key.is_a?(Symbol) || key.is_a?(Array)
|
10
|
+
|
11
|
+
raise ArgumentError, ERROR_MESSAGE
|
12
|
+
end
|
13
|
+
|
14
|
+
def validate_each(record, attribute, association_or_value)
|
15
|
+
reflection = record.class._reflect_on_association(attribute)
|
16
|
+
if reflection
|
17
|
+
return unless reflection.is_a?(ActiveEntity::Reflection::EmbeddedAssociationReflection)
|
18
|
+
return unless reflection.collection?
|
19
|
+
end
|
20
|
+
|
21
|
+
indexed_attribute =
|
22
|
+
if reflection
|
23
|
+
reflection.options[:index_errors] || ActiveEntity::Base.index_nested_attribute_errors
|
24
|
+
else
|
25
|
+
options[:index_errors] || true
|
26
|
+
end
|
27
|
+
|
28
|
+
association_or_value =
|
29
|
+
if reflection
|
30
|
+
Array.wrap(association_or_value).reject(&:marked_for_destruction?)
|
31
|
+
else
|
32
|
+
Array.wrap(association_or_value)
|
33
|
+
end
|
34
|
+
|
35
|
+
return if association_or_value.size <= 1
|
36
|
+
|
37
|
+
duplicate_records =
|
38
|
+
if key.is_a? Symbol
|
39
|
+
association_or_value.group_by(&key)
|
40
|
+
elsif key.is_a? Array
|
41
|
+
association_or_value.group_by { |r| key.map { |attr| r.send(attr) } }
|
42
|
+
end
|
43
|
+
.values
|
44
|
+
.select { |v| v.size > 1 }
|
45
|
+
.flatten
|
46
|
+
|
47
|
+
return if duplicate_records.empty?
|
48
|
+
|
49
|
+
duplicate_records.each do |r|
|
50
|
+
if key.is_a? Symbol
|
51
|
+
r.errors.add(key, :duplicated, options)
|
52
|
+
|
53
|
+
# Hack the record
|
54
|
+
normalized_attribute = normalize_attribute(attribute, indexed_attribute, association_or_value.index(r), key)
|
55
|
+
record.errors[normalized_attribute].concat r.errors.messages[key]
|
56
|
+
record.errors[normalized_attribute].uniq!
|
57
|
+
|
58
|
+
record.errors.details[normalized_attribute.to_sym].concat r.errors.details[key]
|
59
|
+
record.errors.details[normalized_attribute.to_sym].uniq!
|
60
|
+
elsif key.is_a? Array
|
61
|
+
key.each do |attr|
|
62
|
+
r.errors.add(attr, :duplicated, options)
|
63
|
+
|
64
|
+
# Hack the record
|
65
|
+
normalized_attribute = normalize_attribute(attribute, indexed_attribute, association_or_value.index(r), attr)
|
66
|
+
record.errors[normalized_attribute].concat r.errors.messages[attr]
|
67
|
+
record.errors[normalized_attribute].uniq!
|
68
|
+
|
69
|
+
record.errors.details[normalized_attribute.to_sym].concat r.errors.details[attr]
|
70
|
+
record.errors.details[normalized_attribute.to_sym].uniq!
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def key
|
79
|
+
@key ||= options[:key]
|
80
|
+
end
|
81
|
+
|
82
|
+
def normalize_attribute(attribute, indexed_attribute, index, nested_attribute)
|
83
|
+
if indexed_attribute
|
84
|
+
"#{attribute}[#{index}].#{nested_attribute}"
|
85
|
+
else
|
86
|
+
"#{attribute}.#{nested_attribute}"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
module ClassMethods
|
92
|
+
# Validates whether the value of the specified attributes are unique
|
93
|
+
# in the embedded association.
|
94
|
+
def validates_uniqueness_in_embedding_of(*attr_names)
|
95
|
+
validates_with UniquenessInEmbeddingValidator, _merge_attributes(attr_names)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
metadata
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: activeentity
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1.beta1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- jasl
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-01-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 6.0.0.beta1
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '7.0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 6.0.0.beta1
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '7.0'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: activemodel
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 6.0.0.beta1
|
40
|
+
- - "<"
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '7.0'
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 6.0.0.beta1
|
50
|
+
- - "<"
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '7.0'
|
53
|
+
description: Rails virtual model solution based on ActiveModel design for Rails 6+.
|
54
|
+
email:
|
55
|
+
- jasl9187@hotmail.com
|
56
|
+
executables: []
|
57
|
+
extensions: []
|
58
|
+
extra_rdoc_files: []
|
59
|
+
files:
|
60
|
+
- MIT-LICENSE
|
61
|
+
- README.md
|
62
|
+
- Rakefile
|
63
|
+
- lib/active_entity.rb
|
64
|
+
- lib/active_entity/aggregations.rb
|
65
|
+
- lib/active_entity/associations.rb
|
66
|
+
- lib/active_entity/associations/embedded/association.rb
|
67
|
+
- lib/active_entity/associations/embedded/builder/association.rb
|
68
|
+
- lib/active_entity/associations/embedded/builder/collection_association.rb
|
69
|
+
- lib/active_entity/associations/embedded/builder/embedded_in.rb
|
70
|
+
- lib/active_entity/associations/embedded/builder/embeds_many.rb
|
71
|
+
- lib/active_entity/associations/embedded/builder/embeds_one.rb
|
72
|
+
- lib/active_entity/associations/embedded/builder/singular_association.rb
|
73
|
+
- lib/active_entity/associations/embedded/collection_association.rb
|
74
|
+
- lib/active_entity/associations/embedded/collection_proxy.rb
|
75
|
+
- lib/active_entity/associations/embedded/embedded_in_association.rb
|
76
|
+
- lib/active_entity/associations/embedded/embeds_many_association.rb
|
77
|
+
- lib/active_entity/associations/embedded/embeds_one_association.rb
|
78
|
+
- lib/active_entity/associations/embedded/singular_association.rb
|
79
|
+
- lib/active_entity/attribute_assignment.rb
|
80
|
+
- lib/active_entity/attribute_decorators.rb
|
81
|
+
- lib/active_entity/attribute_methods.rb
|
82
|
+
- lib/active_entity/attribute_methods/before_type_cast.rb
|
83
|
+
- lib/active_entity/attribute_methods/primary_key.rb
|
84
|
+
- lib/active_entity/attribute_methods/query.rb
|
85
|
+
- lib/active_entity/attribute_methods/read.rb
|
86
|
+
- lib/active_entity/attribute_methods/serialization.rb
|
87
|
+
- lib/active_entity/attribute_methods/time_zone_conversion.rb
|
88
|
+
- lib/active_entity/attribute_methods/write.rb
|
89
|
+
- lib/active_entity/attributes.rb
|
90
|
+
- lib/active_entity/base.rb
|
91
|
+
- lib/active_entity/coders/json.rb
|
92
|
+
- lib/active_entity/coders/yaml_column.rb
|
93
|
+
- lib/active_entity/core.rb
|
94
|
+
- lib/active_entity/define_callbacks.rb
|
95
|
+
- lib/active_entity/enum.rb
|
96
|
+
- lib/active_entity/errors.rb
|
97
|
+
- lib/active_entity/gem_version.rb
|
98
|
+
- lib/active_entity/inheritance.rb
|
99
|
+
- lib/active_entity/integration.rb
|
100
|
+
- lib/active_entity/locale/en.yml
|
101
|
+
- lib/active_entity/model_schema.rb
|
102
|
+
- lib/active_entity/nested_attributes.rb
|
103
|
+
- lib/active_entity/readonly_attributes.rb
|
104
|
+
- lib/active_entity/reflection.rb
|
105
|
+
- lib/active_entity/serialization.rb
|
106
|
+
- lib/active_entity/store.rb
|
107
|
+
- lib/active_entity/translation.rb
|
108
|
+
- lib/active_entity/type.rb
|
109
|
+
- lib/active_entity/type/date.rb
|
110
|
+
- lib/active_entity/type/date_time.rb
|
111
|
+
- lib/active_entity/type/decimal_without_scale.rb
|
112
|
+
- lib/active_entity/type/hash_lookup_type_map.rb
|
113
|
+
- lib/active_entity/type/internal/timezone.rb
|
114
|
+
- lib/active_entity/type/json.rb
|
115
|
+
- lib/active_entity/type/modifiers/array.rb
|
116
|
+
- lib/active_entity/type/registry.rb
|
117
|
+
- lib/active_entity/type/serialized.rb
|
118
|
+
- lib/active_entity/type/text.rb
|
119
|
+
- lib/active_entity/type/time.rb
|
120
|
+
- lib/active_entity/type/type_map.rb
|
121
|
+
- lib/active_entity/type/unsigned_integer.rb
|
122
|
+
- lib/active_entity/validate_embedded_association.rb
|
123
|
+
- lib/active_entity/validations.rb
|
124
|
+
- lib/active_entity/validations/absence.rb
|
125
|
+
- lib/active_entity/validations/associated.rb
|
126
|
+
- lib/active_entity/validations/length.rb
|
127
|
+
- lib/active_entity/validations/presence.rb
|
128
|
+
- lib/active_entity/validations/subset.rb
|
129
|
+
- lib/active_entity/validations/uniqueness_in_embedding.rb
|
130
|
+
- lib/active_entity/version.rb
|
131
|
+
- lib/tasks/active_entity_tasks.rake
|
132
|
+
homepage: https://github.com/jasl/activeentity
|
133
|
+
licenses:
|
134
|
+
- MIT
|
135
|
+
metadata: {}
|
136
|
+
post_install_message:
|
137
|
+
rdoc_options: []
|
138
|
+
require_paths:
|
139
|
+
- lib
|
140
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: 2.5.0
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - ">"
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: 1.3.1
|
150
|
+
requirements: []
|
151
|
+
rubygems_version: 3.0.2
|
152
|
+
signing_key:
|
153
|
+
specification_version: 4
|
154
|
+
summary: Rails virtual model solution based on ActiveModel.
|
155
|
+
test_files: []
|