active_data 1.0.0 → 1.1.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.
Files changed (115) hide show
  1. checksums.yaml +5 -5
  2. data/.codeclimate.yml +13 -0
  3. data/.rubocop.yml +56 -0
  4. data/.rubocop_todo.yml +53 -0
  5. data/.rvmrc +1 -1
  6. data/.travis.yml +15 -2
  7. data/Appraisals +1 -1
  8. data/CHANGELOG.md +31 -0
  9. data/Guardfile +8 -8
  10. data/README.md +256 -0
  11. data/Rakefile +2 -4
  12. data/active_data.gemspec +8 -7
  13. data/gemfiles/rails.4.0.gemfile +1 -1
  14. data/gemfiles/rails.4.1.gemfile +1 -1
  15. data/gemfiles/rails.4.2.gemfile +1 -1
  16. data/gemfiles/rails.5.0.gemfile +1 -1
  17. data/gemfiles/rails.5.1.gemfile +14 -0
  18. data/lib/active_data/active_record/associations.rb +18 -13
  19. data/lib/active_data/active_record/nested_attributes.rb +8 -14
  20. data/lib/active_data/base.rb +13 -0
  21. data/lib/active_data/config.rb +4 -4
  22. data/lib/active_data/errors.rb +29 -13
  23. data/lib/active_data/extensions.rb +22 -21
  24. data/lib/active_data/model/associations/base.rb +22 -6
  25. data/lib/active_data/model/associations/embeds_any.rb +17 -0
  26. data/lib/active_data/model/associations/embeds_many.rb +29 -19
  27. data/lib/active_data/model/associations/embeds_one.rb +30 -26
  28. data/lib/active_data/model/associations/nested_attributes.rb +82 -50
  29. data/lib/active_data/model/associations/persistence_adapters/active_record/referenced_proxy.rb +31 -0
  30. data/lib/active_data/model/associations/persistence_adapters/active_record.rb +66 -0
  31. data/lib/active_data/model/associations/persistence_adapters/base.rb +53 -0
  32. data/lib/active_data/model/associations/references_any.rb +41 -0
  33. data/lib/active_data/model/associations/references_many.rb +51 -37
  34. data/lib/active_data/model/associations/references_one.rb +43 -41
  35. data/lib/active_data/model/associations/reflections/base.rb +19 -29
  36. data/lib/active_data/model/associations/reflections/embeds_any.rb +43 -0
  37. data/lib/active_data/model/associations/reflections/embeds_many.rb +3 -13
  38. data/lib/active_data/model/associations/reflections/embeds_one.rb +5 -37
  39. data/lib/active_data/model/associations/reflections/references_any.rb +62 -0
  40. data/lib/active_data/model/associations/reflections/references_many.rb +7 -7
  41. data/lib/active_data/model/associations/reflections/references_one.rb +9 -7
  42. data/lib/active_data/model/associations/reflections/singular.rb +35 -0
  43. data/lib/active_data/model/associations/validations.rb +2 -27
  44. data/lib/active_data/model/associations.rb +12 -10
  45. data/lib/active_data/model/attributes/attribute.rb +10 -10
  46. data/lib/active_data/model/attributes/base.rb +8 -7
  47. data/lib/active_data/model/attributes/localized.rb +4 -4
  48. data/lib/active_data/model/attributes/reference_many.rb +6 -8
  49. data/lib/active_data/model/attributes/reference_one.rb +17 -9
  50. data/lib/active_data/model/attributes/reflections/attribute.rb +2 -2
  51. data/lib/active_data/model/attributes/reflections/base.rb +8 -11
  52. data/lib/active_data/model/attributes/reflections/localized.rb +2 -2
  53. data/lib/active_data/model/attributes/reflections/reference_one.rb +11 -22
  54. data/lib/active_data/model/attributes/reflections/represents.rb +5 -6
  55. data/lib/active_data/model/attributes/represents.rb +6 -5
  56. data/lib/active_data/model/attributes.rb +33 -87
  57. data/lib/active_data/model/callbacks.rb +6 -7
  58. data/lib/active_data/model/conventions.rb +2 -0
  59. data/lib/active_data/model/dirty.rb +4 -4
  60. data/lib/active_data/model/lifecycle.rb +18 -20
  61. data/lib/active_data/model/localization.rb +5 -2
  62. data/lib/active_data/model/persistence.rb +2 -2
  63. data/lib/active_data/model/primary.rb +19 -14
  64. data/lib/active_data/model/representation.rb +81 -0
  65. data/lib/active_data/model/scopes.rb +22 -12
  66. data/lib/active_data/model/validations/associated.rb +3 -2
  67. data/lib/active_data/model/validations/nested.rb +6 -1
  68. data/lib/active_data/model/validations.rb +3 -3
  69. data/lib/active_data/model.rb +2 -1
  70. data/lib/active_data/undefined_class.rb +9 -0
  71. data/lib/active_data/version.rb +1 -1
  72. data/lib/active_data.rb +40 -17
  73. data/spec/lib/active_data/active_record/associations_spec.rb +107 -45
  74. data/spec/lib/active_data/active_record/nested_attributes_spec.rb +1 -2
  75. data/spec/lib/active_data/config_spec.rb +37 -15
  76. data/spec/lib/active_data/model/associations/embeds_many_spec.rb +475 -172
  77. data/spec/lib/active_data/model/associations/embeds_one_spec.rb +353 -96
  78. data/spec/lib/active_data/model/associations/nested_attributes_spec.rb +108 -12
  79. data/spec/lib/active_data/model/associations/persistence_adapters/active_record_spec.rb +58 -0
  80. data/spec/lib/active_data/model/associations/references_many_spec.rb +440 -64
  81. data/spec/lib/active_data/model/associations/references_one_spec.rb +347 -36
  82. data/spec/lib/active_data/model/associations/reflections/embeds_many_spec.rb +8 -7
  83. data/spec/lib/active_data/model/associations/reflections/embeds_one_spec.rb +7 -6
  84. data/spec/lib/active_data/model/associations/reflections/references_many_spec.rb +81 -33
  85. data/spec/lib/active_data/model/associations/reflections/references_one_spec.rb +116 -37
  86. data/spec/lib/active_data/model/associations/validations_spec.rb +27 -43
  87. data/spec/lib/active_data/model/associations_spec.rb +34 -25
  88. data/spec/lib/active_data/model/attributes/attribute_spec.rb +26 -23
  89. data/spec/lib/active_data/model/attributes/base_spec.rb +5 -6
  90. data/spec/lib/active_data/model/attributes/collection_spec.rb +7 -8
  91. data/spec/lib/active_data/model/attributes/dictionary_spec.rb +40 -33
  92. data/spec/lib/active_data/model/attributes/localized_spec.rb +27 -28
  93. data/spec/lib/active_data/model/attributes/reflections/attribute_spec.rb +6 -6
  94. data/spec/lib/active_data/model/attributes/represents_spec.rb +10 -78
  95. data/spec/lib/active_data/model/attributes_spec.rb +150 -45
  96. data/spec/lib/active_data/model/callbacks_spec.rb +69 -70
  97. data/spec/lib/active_data/model/conventions_spec.rb +0 -1
  98. data/spec/lib/active_data/model/dirty_spec.rb +22 -13
  99. data/spec/lib/active_data/model/lifecycle_spec.rb +49 -23
  100. data/spec/lib/active_data/model/persistence_spec.rb +5 -6
  101. data/spec/lib/active_data/model/representation_spec.rb +126 -0
  102. data/spec/lib/active_data/model/scopes_spec.rb +1 -3
  103. data/spec/lib/active_data/model/typecasting_spec.rb +6 -5
  104. data/spec/lib/active_data/model/validations/associated_spec.rb +26 -18
  105. data/spec/lib/active_data/model/validations/nested_spec.rb +89 -18
  106. data/spec/lib/active_data/model_spec.rb +1 -2
  107. data/spec/lib/active_data_spec.rb +0 -1
  108. data/spec/shared/nested_attribute_examples.rb +332 -0
  109. data/spec/spec_helper.rb +3 -0
  110. data/spec/support/model_helpers.rb +2 -2
  111. data/spec/support/muffle_helper.rb +7 -0
  112. metadata +52 -18
  113. data/lib/active_data/model/associations/collection/referenced.rb +0 -26
  114. data/lib/active_data/model/associations/reflections/reference_reflection.rb +0 -45
  115. data/spec/lib/active_data/model/nested_attributes.rb +0 -202
@@ -2,13 +2,13 @@ module ActiveData
2
2
  module Model
3
3
  module Attributes
4
4
  class ReferenceOne < Base
5
- def write value
5
+ def write(value)
6
6
  pollute do
7
7
  previous = type_casted_value
8
8
  result = write_value value
9
- if (!value.nil? && type_casted_value.nil?) || type_casted_value != previous
10
- association.reset
11
- end
9
+ changed = (!value.nil? && type_casted_value.nil?) || type_casted_value != previous
10
+
11
+ association.reset if changed
12
12
  result
13
13
  end
14
14
  end
@@ -21,18 +21,26 @@ module ActiveData
21
21
  end
22
22
  end
23
23
 
24
+ def type_casted_value
25
+ variable_cache(:value) do
26
+ typecast(read_before_type_cast)
27
+ end
28
+ end
29
+
24
30
  def read_before_type_cast
25
31
  @value_cache
26
32
  end
27
33
 
28
- private
34
+ def type
35
+ @type ||= association.reflection.persistence_adapter.primary_key_type
36
+ end
29
37
 
30
- def type_casted_value
31
- variable_cache(:value) do
32
- typecast(read_before_type_cast)
33
- end
38
+ def typecaster
39
+ @typecaster ||= ActiveData.typecaster(type.ancestors.grep(Class))
34
40
  end
35
41
 
42
+ private
43
+
36
44
  def association
37
45
  @association ||= owner.association(reflection.association)
38
46
  end
@@ -3,13 +3,13 @@ module ActiveData
3
3
  module Attributes
4
4
  module Reflections
5
5
  class Attribute < Base
6
- def self.build target, generated_methods, name, *args, &block
6
+ def self.build(target, generated_methods, name, *args, &block)
7
7
  attribute = super(target, generated_methods, name, *args, &block)
8
8
  generate_methods name, generated_methods
9
9
  attribute
10
10
  end
11
11
 
12
- def self.generate_methods name, target
12
+ def self.generate_methods(name, target)
13
13
  target.class_eval <<-RUBY, __FILE__, __LINE__ + 1
14
14
  def #{name}
15
15
  attribute('#{name}').read
@@ -5,37 +5,34 @@ module ActiveData
5
5
  class Base
6
6
  attr_reader :name, :options
7
7
  class << self
8
- def build target, generated_methods, name, *args, &block
8
+ def build(_target, _generated_methods, name, *args, &block)
9
9
  options = args.extract_options!
10
- options.merge!(type: args.first) if args.first
11
- options.merge!(default: block) if block
10
+ options[:type] = args.first if args.first
11
+ options[:default] = block if block
12
12
  new(name, options)
13
13
  end
14
14
 
15
- def generate_methods name, target
16
- end
15
+ def generate_methods(name, target) end
17
16
 
18
17
  def attribute_class
19
18
  @attribute_class ||= "ActiveData::Model::Attributes::#{name.demodulize}".constantize
20
19
  end
21
20
  end
22
21
 
23
- def initialize name, options = {}
22
+ def initialize(name, options = {})
24
23
  @name = name.to_s
25
24
  @options = options
26
25
  end
27
26
 
28
- def build_attribute owner, raw_value = nil
27
+ def build_attribute(owner, raw_value = ActiveData::UNDEFINED)
29
28
  attribute = self.class.attribute_class.new(name, owner)
30
- attribute.write_value(raw_value) if raw_value
29
+ attribute.write_value(raw_value) unless raw_value == ActiveData::UNDEFINED
31
30
  attribute
32
31
  end
33
32
 
34
33
  def type
35
34
  @type ||= case options[:type]
36
- when Proc
37
- options[:type].call
38
- when Class
35
+ when Class, Module
39
36
  options[:type]
40
37
  when nil
41
38
  raise "Type is not specified for `#{name}`"
@@ -3,13 +3,13 @@ module ActiveData
3
3
  module Attributes
4
4
  module Reflections
5
5
  class Localized < Attribute
6
- def self.build target, generated_methods, name, *args, &block
6
+ def self.build(target, generated_methods, name, *args, &block)
7
7
  attribute = super(target, generated_methods, name, *args, &block)
8
8
  generate_methods name, generated_methods
9
9
  attribute
10
10
  end
11
11
 
12
- def self.generate_methods name, target
12
+ def self.generate_methods(name, target)
13
13
  target.class_eval <<-RUBY, __FILE__, __LINE__ + 1
14
14
  def #{name}_translations
15
15
  attribute('#{name}').read
@@ -3,32 +3,13 @@ module ActiveData
3
3
  module Attributes
4
4
  module Reflections
5
5
  class ReferenceOne < Base
6
- TYPES = {
7
- integer: Integer,
8
- float: Float,
9
- decimal: BigDecimal,
10
- datetime: Time,
11
- timestamp: Time,
12
- time: Time,
13
- date: Date,
14
- text: String,
15
- string: String,
16
- binary: String,
17
- boolean: Boolean
18
- }
19
-
20
- def self.build target, generated_methods, name, *args, &block
6
+ def self.build(_target, generated_methods, name, *args)
21
7
  options = args.extract_options!
22
8
  generate_methods name, generated_methods
23
- type_proc = -> {
24
- reflection = target.reflect_on_association(options[:association])
25
- column = reflection.klass.columns_hash[reflection.primary_key.to_s]
26
- TYPES[column.type]
27
- }
28
- new(name, options.reverse_merge(type: type_proc))
9
+ new(name, options)
29
10
  end
30
11
 
31
- def self.generate_methods name, target
12
+ def self.generate_methods(name, target)
32
13
  target.class_eval <<-RUBY, __FILE__, __LINE__ + 1
33
14
  def #{name}
34
15
  attribute('#{name}').read
@@ -48,6 +29,14 @@ module ActiveData
48
29
  RUBY
49
30
  end
50
31
 
32
+ def type
33
+ Object
34
+ end
35
+
36
+ def inspect_reflection
37
+ "#{name}: (reference)"
38
+ end
39
+
51
40
  def association
52
41
  @association ||= options[:association].to_s
53
42
  end
@@ -3,20 +3,19 @@ module ActiveData
3
3
  module Attributes
4
4
  module Reflections
5
5
  class Represents < Attribute
6
- def self.build target, generated_methods, name, *args, &block
6
+ def self.build(target, generated_methods, name, *args, &block)
7
7
  options = args.extract_options!
8
8
 
9
9
  reference = target.reflect_on_association(options[:of]) if target.respond_to?(:reflect_on_association)
10
10
  reference ||= target.reflect_on_attribute(options[:of]) if target.respond_to?(:reflect_on_attribute)
11
- if reference
12
- options[:of] = reference.name
13
- target.validates_nested options[:of]
14
- end
11
+ options[:of] = reference.name if reference
12
+ validates_nested = target.respond_to?(:validates_nested) && !target.validates_nested?(options[:of])
13
+ target.validates_nested(options[:of]) if validates_nested
15
14
 
16
15
  super(target, generated_methods, name, *args, options, &block)
17
16
  end
18
17
 
19
- def initialize name, options
18
+ def initialize(name, options)
20
19
  super
21
20
  raise ArgumentError, "Undefined reference for `#{name}`" if reference.blank?
22
21
  end
@@ -4,7 +4,7 @@ module ActiveData
4
4
  class Represents < Attribute
5
5
  delegate :reader, :reader_before_type_cast, :writer, to: :reflection
6
6
 
7
- def write value
7
+ def write(value)
8
8
  return if readonly?
9
9
  pollute do
10
10
  reset
@@ -48,10 +48,11 @@ module ActiveData
48
48
 
49
49
  def read_value_before_type_cast
50
50
  ref = reference
51
- if ref
52
- ref.respond_to?(reader_before_type_cast) ?
53
- ref.public_send(reader_before_type_cast) :
54
- ref.public_send(reader)
51
+ return unless ref
52
+ if ref.respond_to?(reader_before_type_cast)
53
+ ref.public_send(reader_before_type_cast)
54
+ else
55
+ ref.public_send(reader)
55
56
  end
56
57
  end
57
58
 
@@ -1,20 +1,12 @@
1
1
  require 'active_data/model/attributes/reflections/base'
2
- require 'active_data/model/attributes/reflections/reference_one'
3
- require 'active_data/model/attributes/reflections/reference_many'
4
2
  require 'active_data/model/attributes/reflections/attribute'
5
3
  require 'active_data/model/attributes/reflections/collection'
6
4
  require 'active_data/model/attributes/reflections/dictionary'
7
- require 'active_data/model/attributes/reflections/localized'
8
- require 'active_data/model/attributes/reflections/represents'
9
5
 
10
6
  require 'active_data/model/attributes/base'
11
- require 'active_data/model/attributes/reference_one'
12
- require 'active_data/model/attributes/reference_many'
13
7
  require 'active_data/model/attributes/attribute'
14
8
  require 'active_data/model/attributes/collection'
15
9
  require 'active_data/model/attributes/dictionary'
16
- require 'active_data/model/attributes/localized'
17
- require 'active_data/model/attributes/represents'
18
10
 
19
11
  module ActiveData
20
12
  module Model
@@ -37,31 +29,21 @@ module ActiveData
37
29
  end
38
30
 
39
31
  module ClassMethods
40
- def represents(*names, &block)
41
- options = names.extract_options!
42
- names.each do |name|
43
- add_attribute(Reflections::Represents, name, options, &block)
44
- end
45
- end
46
-
47
32
  def add_attribute(reflection_class, *args, &block)
48
33
  reflection = reflection_class.build(self, generated_attributes_methods, *args, &block)
49
34
  self._attributes = _attributes.merge(reflection.name => reflection)
50
- if dirty? && reflection_class != ActiveData::Model::Attributes::Reflections::Base
51
- define_dirty reflection.name, generated_attributes_methods
52
- end
35
+ should_define_dirty = (dirty? && reflection_class != ActiveData::Model::Attributes::Reflections::Base)
36
+ define_dirty(reflection.name, generated_attributes_methods) if should_define_dirty
53
37
  reflection
54
38
  end
55
39
 
56
40
  def alias_attribute(alias_name, attribute_name)
57
41
  reflection = reflect_on_attribute(attribute_name)
58
- raise ArgumentError.new("Unable to alias undefined attribute `#{attribute_name}` on #{self}") unless reflection
59
- raise ArgumentError.new("Unable to alias base attribute `#{attribute_name}`") if reflection.class == ActiveData::Model::Attributes::Reflections::Base
42
+ raise ArgumentError, "Unable to alias undefined attribute `#{attribute_name}` on #{self}" unless reflection
43
+ raise ArgumentError, "Unable to alias base attribute `#{attribute_name}`" if reflection.class == ActiveData::Model::Attributes::Reflections::Base
60
44
  reflection.class.generate_methods alias_name, generated_attributes_methods
61
45
  self._attribute_aliases = _attribute_aliases.merge(alias_name.to_s => reflection.name)
62
- if dirty?
63
- define_dirty alias_name, generated_attributes_methods
64
- end
46
+ define_dirty alias_name, generated_attributes_methods if dirty?
65
47
  reflection
66
48
  end
67
49
 
@@ -70,7 +52,7 @@ module ActiveData
70
52
  _attributes[_attribute_aliases[name] || name]
71
53
  end
72
54
 
73
- def has_attribute? name
55
+ def has_attribute?(name) # rubocop:disable Naming/PredicateName
74
56
  name = name.to_s
75
57
  _attributes.key?(_attribute_aliases[name] || name)
76
58
  end
@@ -89,24 +71,13 @@ module ActiveData
89
71
  "#{original_inspect}(#{attributes_for_inspect.presence || 'no attributes'})"
90
72
  end
91
73
 
92
- def represented_attributes
93
- @represented_attributes ||= _attributes.values.select do |attribute|
94
- attribute.is_a? ActiveData::Model::Attributes::Reflections::Represents
95
- end
96
- end
97
-
98
- def represented_names_and_aliases
99
- @represented_names_and_aliases ||= represented_attributes.flat_map do |attribute|
100
- [attribute.name, *inverted_attribute_aliases[attribute.name]]
101
- end
102
- end
103
-
104
74
  def dirty?
105
75
  false
106
76
  end
107
77
 
108
78
  def with_sanitize(value)
109
- previous_sanitize, self._sanitize = _sanitize, value
79
+ previous_sanitize = _sanitize
80
+ self._sanitize = value
110
81
  yield
111
82
  ensure
112
83
  self._sanitize = previous_sanitize
@@ -120,7 +91,7 @@ module ActiveData
120
91
 
121
92
  def attributes_for_inspect
122
93
  attribute_names(false).map do |name|
123
- prefix = respond_to?(:_primary_name) && _primary_name == name ? ?* : ''
94
+ prefix = respond_to?(:_primary_name) && _primary_name == name ? '*' : ''
124
95
  "#{prefix}#{_attributes[name].inspect_reflection}"
125
96
  end.join(', ')
126
97
  end
@@ -128,7 +99,7 @@ module ActiveData
128
99
  def generated_attributes_methods
129
100
  @generated_attributes_methods ||=
130
101
  const_set(:GeneratedAttributesMethods, Module.new)
131
- .tap { |proxy| include proxy }
102
+ .tap { |proxy| include proxy }
132
103
  end
133
104
 
134
105
  def inverted_attribute_aliases
@@ -139,37 +110,38 @@ module ActiveData
139
110
  end
140
111
  end
141
112
 
142
- def initialize attrs = {}
113
+ def initialize(attrs = {})
143
114
  assign_attributes attrs
144
115
  end
145
116
 
146
- def == other
117
+ def ==(other)
147
118
  super || other.instance_of?(self.class) && other.attributes(false) == attributes(false)
148
119
  end
149
120
  alias_method :eql?, :==
150
121
 
151
122
  def attribute(name)
152
- if reflection = self.class.reflect_on_attribute(name)
153
- (@_attributes ||= {})[reflection.name] ||= reflection
154
- .build_attribute(self, @initial_attributes.try(:[], reflection.name))
155
- end
123
+ reflection = self.class.reflect_on_attribute(name)
124
+ return unless reflection
125
+ initial_value = @initial_attributes.to_h.fetch(reflection.name, ActiveData::UNDEFINED)
126
+ @_attributes ||= {}
127
+ @_attributes[reflection.name] ||= reflection.build_attribute(self, initial_value)
156
128
  end
157
129
 
158
- def write_attribute name, value
130
+ def write_attribute(name, value)
159
131
  attribute(name).write(value)
160
132
  end
161
133
  alias_method :[]=, :write_attribute
162
134
 
163
- def read_attribute name
135
+ def read_attribute(name)
164
136
  attribute(name).read
165
137
  end
166
138
  alias_method :[], :read_attribute
167
139
 
168
- def read_attribute_before_type_cast name
140
+ def read_attribute_before_type_cast(name)
169
141
  attribute(name).read_before_type_cast
170
142
  end
171
143
 
172
- def attribute_present? name
144
+ def attribute_present?(name)
173
145
  attribute(name).value_present?
174
146
  end
175
147
 
@@ -177,35 +149,22 @@ module ActiveData
177
149
  Hash[attribute_names(include_associations).map { |name| [name, read_attribute(name)] }]
178
150
  end
179
151
 
180
- def update attrs
152
+ def update(attrs)
181
153
  assign_attributes(attrs)
182
154
  end
183
155
  alias_method :update_attributes, :update
184
156
 
185
- def assign_attributes attrs
186
- if self.class.represented_attributes.present? ||
187
- (self.class.is_a?(ActiveData::Model::Associations::NestedAttributes) &&
188
- self.class.nested_attributes_options.present?)
189
- attrs.stringify_keys!
190
- represented_attrs = self.class.represented_names_and_aliases
191
- .each_with_object({}) do |name, result|
192
- result[name] = attrs.delete(name) if attrs.has_key?(name)
193
- end
194
- if self.class.is_a?(ActiveData::Model::Associations::NestedAttributes)
195
- nested_attrs = self.class.nested_attributes_options.keys
196
- .each_with_object({}) do |association_name, result|
197
- name = "#{association_name}_attributes"
198
- result[name] = attrs.delete(name) if attrs.has_key?(name)
199
- end
200
- end
157
+ def assign_attributes(attrs)
158
+ attrs.each do |name, value|
159
+ name = name.to_s
160
+ sanitize_value = self.class._sanitize && name == self.class.primary_name
201
161
 
202
- _assign_attributes(attrs)
203
- _assign_attributes(represented_attrs)
204
- _assign_attributes(nested_attrs) if nested_attrs
205
- else
206
- _assign_attributes(attrs)
162
+ if respond_to?("#{name}=") && !sanitize_value
163
+ public_send("#{name}=", value)
164
+ else
165
+ logger.info("Ignoring #{sanitize_value ? 'primary' : 'undefined'} `#{name}` attribute value for #{self} during mass-assignment")
166
+ end
207
167
  end
208
- true
209
168
  end
210
169
  alias_method :attributes=, :assign_attributes
211
170
 
@@ -213,7 +172,7 @@ module ActiveData
213
172
  "#<#{self.class.send(:original_inspect)} #{attributes_for_inspect.presence || '(no attributes)'}>"
214
173
  end
215
174
 
216
- def initialize_copy _
175
+ def initialize_copy(_)
217
176
  @initial_attributes = Hash[attribute_names.map do |name|
218
177
  [name, read_attribute_before_type_cast(name)]
219
178
  end]
@@ -223,22 +182,9 @@ module ActiveData
223
182
 
224
183
  private
225
184
 
226
- def _assign_attributes attrs
227
- attrs.each do |name, value|
228
- name = name.to_s
229
- sanitize_value = self.class._sanitize && name == self.class.primary_name
230
-
231
- if respond_to?("#{name}=") && !sanitize_value
232
- public_send("#{name}=", value)
233
- else
234
- logger.info("Ignoring #{sanitize_value ? 'primary' : 'undefined'} `#{name}` attribute value for #{self} during mass-assignment")
235
- end
236
- end
237
- end
238
-
239
185
  def attributes_for_inspect
240
186
  attribute_names(false).map do |name|
241
- prefix = self.class.primary_name == name ? ?* : ''
187
+ prefix = self.class.primary_name == name ? '*' : ''
242
188
  "#{prefix}#{attribute(name).inspect_attribute}"
243
189
  end.join(', ')
244
190
  end
@@ -1,6 +1,5 @@
1
1
  module ActiveData
2
2
  module Model
3
-
4
3
  # == Callbacks for ActiveData::Model lifecycle
5
4
  #
6
5
  # Provides ActiveModel callbacks support for lifecycle
@@ -45,24 +44,24 @@ module ActiveData
45
44
  end
46
45
 
47
46
  module PrependMethods
48
- def initialize *_
49
- super(*_)
47
+ def initialize(*_)
48
+ super
50
49
  run_callbacks :initialize
51
50
  end
52
51
 
53
- def save_object &block
52
+ def save_object(&block)
54
53
  run_callbacks(:save) { super(&block) }
55
54
  end
56
55
 
57
- def create_object &block
56
+ def create_object(&block)
58
57
  run_callbacks(:create) { super(&block) }
59
58
  end
60
59
 
61
- def update_object &block
60
+ def update_object(&block)
62
61
  run_callbacks(:update) { super(&block) }
63
62
  end
64
63
 
65
- def destroy_object &block
64
+ def destroy_object(&block)
66
65
  run_callbacks(:destroy) { super(&block) }
67
66
  end
68
67
  end
@@ -4,6 +4,8 @@ module ActiveData
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  included do
7
+ attr_reader :embedder
8
+
7
9
  delegate :logger, to: ActiveData
8
10
  self.include_root_in_json = ActiveData.include_root_in_json
9
11
  end
@@ -12,8 +12,8 @@ module ActiveData
12
12
  def self.append_features(base)
13
13
  unconcerned_append_features(base)
14
14
  end
15
- def self.included(base)
16
- end
15
+
16
+ def self.included(_base); end
17
17
  end
18
18
 
19
19
  included do
@@ -42,13 +42,13 @@ module ActiveData
42
42
  attribute_names(false).each do |name|
43
43
  define_dirty name, generated_attributes_methods
44
44
  end
45
- _attribute_aliases.keys.each do |name|
45
+ _attribute_aliases.each_key do |name|
46
46
  define_dirty name, generated_attributes_methods
47
47
  end
48
48
  end
49
49
 
50
50
  module ClassMethods
51
- def define_dirty method, target = self
51
+ def define_dirty(method, target = self)
52
52
  reflection = reflect_on_attribute(method)
53
53
  name = reflection ? reflection.name : method
54
54