activeentity 0.0.1.beta1
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|