duck_record 0.0.9.1 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +13 -13
  3. data/lib/duck_record/associations/association.rb +15 -15
  4. data/lib/duck_record/associations/collection_association.rb +8 -8
  5. data/lib/duck_record/associations/collection_proxy.rb +1 -1
  6. data/lib/duck_record/associations/has_many_association.rb +0 -1
  7. data/lib/duck_record/associations/singular_association.rb +6 -6
  8. data/lib/duck_record/attribute/user_provided_default.rb +2 -2
  9. data/lib/duck_record/attribute.rb +70 -70
  10. data/lib/duck_record/attribute_assignment.rb +74 -74
  11. data/lib/duck_record/attribute_methods/before_type_cast.rb +9 -9
  12. data/lib/duck_record/attribute_methods/dirty.rb +29 -29
  13. data/lib/duck_record/attribute_methods/read.rb +27 -27
  14. data/lib/duck_record/attribute_methods/write.rb +20 -20
  15. data/lib/duck_record/attribute_methods.rb +8 -8
  16. data/lib/duck_record/attribute_mutation_tracker.rb +4 -4
  17. data/lib/duck_record/attribute_set/yaml_encoder.rb +5 -5
  18. data/lib/duck_record/attribute_set.rb +5 -5
  19. data/lib/duck_record/attributes.rb +14 -14
  20. data/lib/duck_record/base.rb +18 -18
  21. data/lib/duck_record/callbacks.rb +1 -1
  22. data/lib/duck_record/core.rb +35 -35
  23. data/lib/duck_record/inheritance.rb +25 -25
  24. data/lib/duck_record/model_schema.rb +10 -11
  25. data/lib/duck_record/nested_attributes.rb +149 -149
  26. data/lib/duck_record/reflection.rb +14 -14
  27. data/lib/duck_record/type/array.rb +6 -6
  28. data/lib/duck_record/type/registry.rb +21 -21
  29. data/lib/duck_record/type/serialized.rb +8 -8
  30. data/lib/duck_record/type/time.rb +0 -1
  31. data/lib/duck_record/type/unsigned_integer.rb +6 -6
  32. data/lib/duck_record/type.rb +16 -14
  33. data/lib/duck_record/validations/uniqueness_on_real_record.rb +45 -45
  34. data/lib/duck_record/validations.rb +6 -6
  35. data/lib/duck_record/version.rb +1 -1
  36. data/lib/duck_record.rb +7 -7
  37. metadata +7 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 14c5a6fb588c5f26c7779a9f4b3bd48971e1a94a
4
- data.tar.gz: 853b2cfd5c430487eb3bd3b05b0ad1fc18b94349
3
+ metadata.gz: b939fb448db977122db882494b644b720cbc693a
4
+ data.tar.gz: c8a2ffdb2f4571f75fc1935f6719fa285faf48f1
5
5
  SHA512:
6
- metadata.gz: f5306ca0879a4d3a32cb32a916a4e32587610c061dd6e76821d96008c755338eb5c86e71a0b19c789e27801504b1ea0709aa597f65e7ab46ac564e2fd4419bf5
7
- data.tar.gz: 296acc961ba9a862c335dabfb08a619293153a97dfe5f753dbcddae7a20e857a2ecd7d4d7be4451f5c9b70e5688c6db31dcd03787fffee13a044831d26fecd0e
6
+ metadata.gz: 5512c1065105dfcb7c0d79e320e1daf27d6bf7d9cecdadcf080cdb9b2150a9bfe7cb5b2ad0b45ab5912c3189af831b005a8544d7f3acc5ecb349c8ce12a44456
7
+ data.tar.gz: ef2cc020e9e153e00d5ef5e3c38dea6bba9d6a6446f10173a177a226b24f0b9198d10c194a0dc9dac4aedd3c770cc55e4c522e1ef89efa3609d9282b34fbd3b2
data/Rakefile CHANGED
@@ -1,27 +1,27 @@
1
1
  begin
2
- require 'bundler/setup'
2
+ require "bundler/setup"
3
3
  rescue LoadError
4
- puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
4
+ puts "You must `gem install bundler` and `bundle install` to run rake tasks"
5
5
  end
6
6
 
7
- require 'rdoc/task'
7
+ require "rdoc/task"
8
8
 
9
9
  RDoc::Task.new(:rdoc) do |rdoc|
10
- rdoc.rdoc_dir = 'rdoc'
11
- rdoc.title = 'DuckRecord'
12
- rdoc.options << '--line-numbers'
13
- rdoc.rdoc_files.include('README.md')
14
- rdoc.rdoc_files.include('lib/**/*.rb')
10
+ rdoc.rdoc_dir = "rdoc"
11
+ rdoc.title = "DuckRecord"
12
+ rdoc.options << "--line-numbers"
13
+ rdoc.rdoc_files.include("README.md")
14
+ rdoc.rdoc_files.include("lib/**/*.rb")
15
15
  end
16
16
 
17
- require 'bundler/gem_tasks'
17
+ require "bundler/gem_tasks"
18
18
 
19
- require 'rake/testtask'
19
+ require "rake/testtask"
20
20
 
21
21
  Rake::TestTask.new(:test) do |t|
22
- t.libs << 'lib'
23
- t.libs << 'test'
24
- t.pattern = 'test/**/*_test.rb'
22
+ t.libs << "lib"
23
+ t.libs << "test"
24
+ t.pattern = "test/**/*_test.rb"
25
25
  t.verbose = false
26
26
  end
27
27
 
@@ -68,25 +68,25 @@ module DuckRecord
68
68
 
69
69
  private
70
70
 
71
- # Raises ActiveRecord::AssociationTypeMismatch unless +record+ is of
72
- # the kind of the class of the associated objects. Meant to be used as
73
- # a sanity check when you are about to assign an associated record.
74
- def raise_on_type_mismatch!(record)
75
- unless record.is_a?(reflection.klass)
76
- fresh_class = reflection.class_name.safe_constantize
77
- unless fresh_class && record.is_a?(fresh_class)
78
- message = "#{reflection.class_name}(##{reflection.klass.object_id}) expected, "\
79
- "got #{record.inspect} which is an instance of #{record.class}(##{record.class.object_id})"
80
- raise ActiveRecord::AssociationTypeMismatch, message
71
+ # Raises ActiveRecord::AssociationTypeMismatch unless +record+ is of
72
+ # the kind of the class of the associated objects. Meant to be used as
73
+ # a sanity check when you are about to assign an associated record.
74
+ def raise_on_type_mismatch!(record)
75
+ unless record.is_a?(reflection.klass)
76
+ fresh_class = reflection.class_name.safe_constantize
77
+ unless fresh_class && record.is_a?(fresh_class)
78
+ message = "#{reflection.class_name}(##{reflection.klass.object_id}) expected, "\
79
+ "got #{record.inspect} which is an instance of #{record.class}(##{record.class.object_id})"
80
+ raise ActiveRecord::AssociationTypeMismatch, message
81
+ end
81
82
  end
82
83
  end
83
- end
84
84
 
85
- def build_record(attributes)
86
- reflection.build_association(attributes) do |record|
87
- initialize_attributes(record, attributes)
85
+ def build_record(attributes)
86
+ reflection.build_association(attributes) do |record|
87
+ initialize_attributes(record, attributes)
88
+ end
88
89
  end
89
- end
90
90
  end
91
91
  end
92
92
  end
@@ -172,16 +172,16 @@ module DuckRecord
172
172
 
173
173
  private
174
174
 
175
- def callback(method, record)
176
- callbacks_for(method).each do |callback|
177
- callback.call(method, owner, record)
175
+ def callback(method, record)
176
+ callbacks_for(method).each do |callback|
177
+ callback.call(method, owner, record)
178
+ end
178
179
  end
179
- end
180
180
 
181
- def callbacks_for(callback_name)
182
- full_callback_name = "#{callback_name}_for_#{reflection.name}"
183
- owner.class.send(full_callback_name)
184
- end
181
+ def callbacks_for(callback_name)
182
+ full_callback_name = "#{callback_name}_for_#{reflection.name}"
183
+ owner.class.send(full_callback_name)
184
+ end
185
185
  end
186
186
  end
187
187
  end
@@ -883,7 +883,7 @@ module DuckRecord
883
883
 
884
884
  def inspect
885
885
  entries = records.take(11).map!(&:inspect)
886
- entries[10] = '...' if entries.size == 11
886
+ entries[10] = "..." if entries.size == 11
887
887
 
888
888
  "#<#{self.class.name} [#{entries.join(', ')}]>"
889
889
  end
@@ -6,7 +6,6 @@ module DuckRecord
6
6
  # If the association has a <tt>:through</tt> option further specialization
7
7
  # is provided by its child HasManyThroughAssociation.
8
8
  class HasManyAssociation < CollectionAssociation #:nodoc:
9
-
10
9
  end
11
10
  end
12
11
  end
@@ -27,13 +27,13 @@ module DuckRecord
27
27
 
28
28
  private
29
29
 
30
- def replace(_record)
31
- raise NotImplementedError, "Subclasses must implement a replace(record) method"
32
- end
30
+ def replace(_record)
31
+ raise NotImplementedError, "Subclasses must implement a replace(record) method"
32
+ end
33
33
 
34
- def set_new_record(record)
35
- replace(record)
36
- end
34
+ def set_new_record(record)
35
+ replace(record)
36
+ end
37
37
  end
38
38
  end
39
39
  end
@@ -1,4 +1,4 @@
1
- require 'duck_record/attribute'
1
+ require "duck_record/attribute"
2
2
 
3
3
  module DuckRecord
4
4
  class Attribute # :nodoc:
@@ -24,7 +24,7 @@ module DuckRecord
24
24
  # Workaround for Ruby 2.2 "private attribute?" warning.
25
25
  protected
26
26
 
27
- attr_reader :user_provided_value
27
+ attr_reader :user_provided_value
28
28
  end
29
29
  end
30
30
  end
@@ -110,104 +110,104 @@ module DuckRecord
110
110
 
111
111
  protected
112
112
 
113
- attr_reader :original_attribute
114
- alias_method :assigned?, :original_attribute
113
+ attr_reader :original_attribute
114
+ alias_method :assigned?, :original_attribute
115
115
 
116
- def initialize_dup(other)
117
- if defined?(@value) && @value.duplicable?
118
- @value = @value.dup
116
+ def initialize_dup(other)
117
+ if defined?(@value) && @value.duplicable?
118
+ @value = @value.dup
119
+ end
119
120
  end
120
- end
121
121
 
122
- def changed_from_assignment?
123
- assigned? && type.changed?(original_value, value, value_before_type_cast)
124
- end
125
-
126
- def original_value_for_database
127
- if assigned?
128
- original_attribute.original_value_for_database
129
- else
130
- _original_value_for_database
122
+ def changed_from_assignment?
123
+ assigned? && type.changed?(original_value, value, value_before_type_cast)
131
124
  end
132
- end
133
125
 
134
- def _original_value_for_database
135
- type.serialize(original_value)
136
- end
137
-
138
- class FromDatabase < Attribute # :nodoc:
139
- def type_cast(value)
140
- type.deserialize(value)
126
+ def original_value_for_database
127
+ if assigned?
128
+ original_attribute.original_value_for_database
129
+ else
130
+ _original_value_for_database
131
+ end
141
132
  end
142
133
 
143
134
  def _original_value_for_database
144
- value_before_type_cast
135
+ type.serialize(original_value)
145
136
  end
146
- end
147
137
 
148
- class FromUser < Attribute # :nodoc:
149
- def type_cast(value)
150
- type.cast(value)
151
- end
138
+ class FromDatabase < Attribute # :nodoc:
139
+ def type_cast(value)
140
+ type.deserialize(value)
141
+ end
152
142
 
153
- def came_from_user?
154
- true
143
+ def _original_value_for_database
144
+ value_before_type_cast
145
+ end
155
146
  end
156
- end
157
147
 
158
- class WithCastValue < Attribute # :nodoc:
159
- def type_cast(value)
160
- value
161
- end
148
+ class FromUser < Attribute # :nodoc:
149
+ def type_cast(value)
150
+ type.cast(value)
151
+ end
162
152
 
163
- def changed_in_place?
164
- false
153
+ def came_from_user?
154
+ true
155
+ end
165
156
  end
166
- end
167
157
 
168
- class Null < Attribute # :nodoc:
169
- def initialize(name)
170
- super(name, nil, Type::Value.new)
171
- end
158
+ class WithCastValue < Attribute # :nodoc:
159
+ def type_cast(value)
160
+ value
161
+ end
172
162
 
173
- def type_cast(*)
174
- nil
163
+ def changed_in_place?
164
+ false
165
+ end
175
166
  end
176
167
 
177
- def with_type(type)
178
- self.class.with_cast_value(name, nil, type)
179
- end
168
+ class Null < Attribute # :nodoc:
169
+ def initialize(name)
170
+ super(name, nil, Type::Value.new)
171
+ end
180
172
 
181
- def with_value_from_database(value)
182
- raise ActiveModel::MissingAttributeError, "can't write unknown attribute `#{name}`"
183
- end
184
- alias_method :with_value_from_user, :with_value_from_database
185
- end
173
+ def type_cast(*)
174
+ nil
175
+ end
186
176
 
187
- class Uninitialized < Attribute # :nodoc:
188
- UNINITIALIZED_ORIGINAL_VALUE = Object.new
177
+ def with_type(type)
178
+ self.class.with_cast_value(name, nil, type)
179
+ end
189
180
 
190
- def initialize(name, type)
191
- super(name, nil, type)
181
+ def with_value_from_database(value)
182
+ raise ActiveModel::MissingAttributeError, "can't write unknown attribute `#{name}`"
183
+ end
184
+ alias_method :with_value_from_user, :with_value_from_database
192
185
  end
193
186
 
194
- def value
195
- if block_given?
196
- yield name
187
+ class Uninitialized < Attribute # :nodoc:
188
+ UNINITIALIZED_ORIGINAL_VALUE = Object.new
189
+
190
+ def initialize(name, type)
191
+ super(name, nil, type)
197
192
  end
198
- end
199
193
 
200
- def original_value
201
- UNINITIALIZED_ORIGINAL_VALUE
202
- end
194
+ def value
195
+ if block_given?
196
+ yield name
197
+ end
198
+ end
203
199
 
204
- def value_for_database
205
- end
200
+ def original_value
201
+ UNINITIALIZED_ORIGINAL_VALUE
202
+ end
206
203
 
207
- def initialized?
208
- false
204
+ def value_for_database
205
+ end
206
+
207
+ def initialized?
208
+ false
209
+ end
209
210
  end
210
- end
211
- private_constant :FromDatabase, :FromUser, :Null, :Uninitialized, :WithCastValue
211
+ private_constant :FromDatabase, :FromUser, :Null, :Uninitialized, :WithCastValue
212
212
  end
213
213
  end
@@ -1,5 +1,5 @@
1
- require 'active_support/core_ext/hash/keys'
2
- require 'active_model/forbidden_attributes_protection'
1
+ require "active_support/core_ext/hash/keys"
2
+ require "active_model/forbidden_attributes_protection"
3
3
 
4
4
  module DuckRecord
5
5
  module AttributeAssignment
@@ -23,97 +23,97 @@ module DuckRecord
23
23
 
24
24
  private
25
25
 
26
- def _assign_attributes(attributes, force_write_readonly: false)
27
- multi_parameter_attributes = {}
28
- nested_parameter_attributes = {}
26
+ def _assign_attributes(attributes, force_write_readonly: false)
27
+ multi_parameter_attributes = {}
28
+ nested_parameter_attributes = {}
29
29
 
30
- attributes.each do |k, v|
31
- if k.include?('(')
32
- multi_parameter_attributes[k] = attributes.delete(k)
33
- elsif v.is_a?(Hash)
34
- nested_parameter_attributes[k] = attributes.delete(k)
30
+ attributes.each do |k, v|
31
+ if k.include?("(")
32
+ multi_parameter_attributes[k] = attributes.delete(k)
33
+ elsif v.is_a?(Hash)
34
+ nested_parameter_attributes[k] = attributes.delete(k)
35
+ end
35
36
  end
36
- end
37
37
 
38
- attributes.each do |k, v|
39
- _assign_attribute(k, v, force_write_readonly: force_write_readonly)
40
- end
38
+ attributes.each do |k, v|
39
+ _assign_attribute(k, v, force_write_readonly: force_write_readonly)
40
+ end
41
41
 
42
- unless nested_parameter_attributes.empty?
43
- assign_nested_parameter_attributes(nested_parameter_attributes, force_write_readonly: force_write_readonly)
44
- end
42
+ unless nested_parameter_attributes.empty?
43
+ assign_nested_parameter_attributes(nested_parameter_attributes, force_write_readonly: force_write_readonly)
44
+ end
45
45
 
46
- unless multi_parameter_attributes.empty?
47
- assign_multiparameter_attributes(multi_parameter_attributes, force_write_readonly: force_write_readonly)
46
+ unless multi_parameter_attributes.empty?
47
+ assign_multiparameter_attributes(multi_parameter_attributes, force_write_readonly: force_write_readonly)
48
+ end
48
49
  end
49
- end
50
50
 
51
- # Assign any deferred nested attributes after the base attributes have been set.
52
- def assign_nested_parameter_attributes(pairs, force_write_readonly: false)
53
- pairs.each { |k, v| _assign_attribute(k, v, force_write_readonly: force_write_readonly) }
54
- end
51
+ # Assign any deferred nested attributes after the base attributes have been set.
52
+ def assign_nested_parameter_attributes(pairs, force_write_readonly: false)
53
+ pairs.each { |k, v| _assign_attribute(k, v, force_write_readonly: force_write_readonly) }
54
+ end
55
55
 
56
- # Instantiates objects for all attribute classes that needs more than one constructor parameter. This is done
57
- # by calling new on the column type or aggregation type (through composed_of) object with these parameters.
58
- # So having the pairs written_on(1) = "2004", written_on(2) = "6", written_on(3) = "24", will instantiate
59
- # written_on (a date type) with Date.new("2004", "6", "24"). You can also specify a typecast character in the
60
- # parentheses to have the parameters typecasted before they're used in the constructor. Use i for Integer and
61
- # f for Float. If all the values for a given attribute are empty, the attribute will be set to +nil+.
62
- def assign_multiparameter_attributes(pairs, force_write_readonly: false)
63
- execute_callstack_for_multiparameter_attributes(
64
- extract_callstack_for_multiparameter_attributes(pairs),
65
- force_write_readonly: force_write_readonly
66
- )
67
- end
56
+ # Instantiates objects for all attribute classes that needs more than one constructor parameter. This is done
57
+ # by calling new on the column type or aggregation type (through composed_of) object with these parameters.
58
+ # So having the pairs written_on(1) = "2004", written_on(2) = "6", written_on(3) = "24", will instantiate
59
+ # written_on (a date type) with Date.new("2004", "6", "24"). You can also specify a typecast character in the
60
+ # parentheses to have the parameters typecasted before they're used in the constructor. Use i for Integer and
61
+ # f for Float. If all the values for a given attribute are empty, the attribute will be set to +nil+.
62
+ def assign_multiparameter_attributes(pairs, force_write_readonly: false)
63
+ execute_callstack_for_multiparameter_attributes(
64
+ extract_callstack_for_multiparameter_attributes(pairs),
65
+ force_write_readonly: force_write_readonly
66
+ )
67
+ end
68
68
 
69
- def execute_callstack_for_multiparameter_attributes(callstack, force_write_readonly: false)
70
- errors = []
71
- callstack.each do |name, values_with_empty_parameters|
72
- begin
73
- if values_with_empty_parameters.each_value.all?(&:nil?)
74
- values = nil
75
- else
76
- values = values_with_empty_parameters
69
+ def execute_callstack_for_multiparameter_attributes(callstack, force_write_readonly: false)
70
+ errors = []
71
+ callstack.each do |name, values_with_empty_parameters|
72
+ begin
73
+ if values_with_empty_parameters.each_value.all?(&:nil?)
74
+ values = nil
75
+ else
76
+ values = values_with_empty_parameters
77
+ end
78
+ send("#{name}=", values, force_write_readonly: force_write_readonly)
79
+ rescue => ex
80
+ errors << AttributeAssignmentError.new("error on assignment #{values_with_empty_parameters.values.inspect} to #{name} (#{ex.message})", ex, name)
77
81
  end
78
- send("#{name}=", values, force_write_readonly: force_write_readonly)
79
- rescue => ex
80
- errors << AttributeAssignmentError.new("error on assignment #{values_with_empty_parameters.values.inspect} to #{name} (#{ex.message})", ex, name)
82
+ end
83
+ unless errors.empty?
84
+ error_descriptions = errors.map(&:message).join(",")
85
+ raise MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes [#{error_descriptions}]"
81
86
  end
82
87
  end
83
- unless errors.empty?
84
- error_descriptions = errors.map(&:message).join(',')
85
- raise MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes [#{error_descriptions}]"
86
- end
87
- end
88
88
 
89
- def extract_callstack_for_multiparameter_attributes(pairs)
90
- attributes = {}
89
+ def extract_callstack_for_multiparameter_attributes(pairs)
90
+ attributes = {}
91
91
 
92
- pairs.each do |(multiparameter_name, value)|
93
- attribute_name = multiparameter_name.split('(').first
94
- attributes[attribute_name] ||= {}
92
+ pairs.each do |(multiparameter_name, value)|
93
+ attribute_name = multiparameter_name.split("(").first
94
+ attributes[attribute_name] ||= {}
95
95
 
96
- parameter_value = value.empty? ? nil : type_cast_attribute_value(multiparameter_name, value)
97
- attributes[attribute_name][find_parameter_position(multiparameter_name)] ||= parameter_value
98
- end
96
+ parameter_value = value.empty? ? nil : type_cast_attribute_value(multiparameter_name, value)
97
+ attributes[attribute_name][find_parameter_position(multiparameter_name)] ||= parameter_value
98
+ end
99
99
 
100
- attributes
101
- end
100
+ attributes
101
+ end
102
102
 
103
- def type_cast_attribute_value(multiparameter_name, value)
104
- multiparameter_name =~ /\([0-9]*([if])\)/ ? value.send('to_' + $1) : value
105
- end
103
+ def type_cast_attribute_value(multiparameter_name, value)
104
+ multiparameter_name =~ /\([0-9]*([if])\)/ ? value.send("to_" + $1) : value
105
+ end
106
106
 
107
- def find_parameter_position(multiparameter_name)
108
- multiparameter_name.scan(/\(([0-9]*).*\)/).first.first.to_i
109
- end
107
+ def find_parameter_position(multiparameter_name)
108
+ multiparameter_name.scan(/\(([0-9]*).*\)/).first.first.to_i
109
+ end
110
110
 
111
- def _assign_attribute(k, v, force_write_readonly: false)
112
- if respond_to?("#{k}=")
113
- public_send("#{k}=", v, force_write_readonly: force_write_readonly)
114
- else
115
- raise UnknownAttributeError.new(self, k)
111
+ def _assign_attribute(k, v, force_write_readonly: false)
112
+ if respond_to?("#{k}=")
113
+ public_send("#{k}=", v, force_write_readonly: force_write_readonly)
114
+ else
115
+ raise UnknownAttributeError.new(self, k)
116
+ end
116
117
  end
117
- end
118
118
  end
119
119
  end
@@ -27,8 +27,8 @@ module DuckRecord
27
27
  extend ActiveSupport::Concern
28
28
 
29
29
  included do
30
- attribute_method_suffix '_before_type_cast'
31
- attribute_method_suffix '_came_from_user?'
30
+ attribute_method_suffix "_before_type_cast"
31
+ attribute_method_suffix "_came_from_user?"
32
32
  end
33
33
 
34
34
  # Returns the value of the attribute identified by +attr_name+ before
@@ -63,14 +63,14 @@ module DuckRecord
63
63
 
64
64
  private
65
65
 
66
- # Handle *_before_type_cast for method_missing.
67
- def attribute_before_type_cast(attribute_name)
68
- read_attribute_before_type_cast(attribute_name)
69
- end
66
+ # Handle *_before_type_cast for method_missing.
67
+ def attribute_before_type_cast(attribute_name)
68
+ read_attribute_before_type_cast(attribute_name)
69
+ end
70
70
 
71
- def attribute_came_from_user?(attribute_name)
72
- @attributes[attribute_name].came_from_user?
73
- end
71
+ def attribute_came_from_user?(attribute_name)
72
+ @attributes[attribute_name].came_from_user?
73
+ end
74
74
  end
75
75
  end
76
76
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
- require 'active_support/core_ext/module/attribute_accessors'
3
- require 'duck_record/attribute_mutation_tracker'
2
+ require "active_support/core_ext/module/attribute_accessors"
3
+ require "duck_record/attribute_mutation_tracker"
4
4
 
5
5
  module DuckRecord
6
6
  module AttributeMethods
@@ -68,40 +68,40 @@ module DuckRecord
68
68
 
69
69
  private
70
70
 
71
- def mutation_tracker
72
- unless defined?(@mutation_tracker)
73
- @mutation_tracker = nil
71
+ def mutation_tracker
72
+ unless defined?(@mutation_tracker)
73
+ @mutation_tracker = nil
74
+ end
75
+ @mutation_tracker ||= AttributeMutationTracker.new(@attributes)
74
76
  end
75
- @mutation_tracker ||= AttributeMutationTracker.new(@attributes)
76
- end
77
77
 
78
- def changes_include?(attr_name)
79
- super || mutation_tracker.changed?(attr_name)
80
- end
78
+ def changes_include?(attr_name)
79
+ super || mutation_tracker.changed?(attr_name)
80
+ end
81
81
 
82
- def clear_attribute_change(attr_name)
83
- mutation_tracker.forget_change(attr_name)
84
- end
82
+ def clear_attribute_change(attr_name)
83
+ mutation_tracker.forget_change(attr_name)
84
+ end
85
85
 
86
- def store_original_attributes
87
- @attributes = @attributes.map(&:forgetting_assignment)
88
- @mutation_tracker = nil
89
- end
86
+ def store_original_attributes
87
+ @attributes = @attributes.map(&:forgetting_assignment)
88
+ @mutation_tracker = nil
89
+ end
90
90
 
91
- def previous_mutation_tracker
92
- @previous_mutation_tracker ||= NullMutationTracker.instance
93
- end
91
+ def previous_mutation_tracker
92
+ @previous_mutation_tracker ||= NullMutationTracker.instance
93
+ end
94
94
 
95
- def cache_changed_attributes
96
- @cached_changed_attributes = changed_attributes
97
- yield
98
- ensure
99
- clear_changed_attributes_cache
100
- end
95
+ def cache_changed_attributes
96
+ @cached_changed_attributes = changed_attributes
97
+ yield
98
+ ensure
99
+ clear_changed_attributes_cache
100
+ end
101
101
 
102
- def clear_changed_attributes_cache
103
- remove_instance_variable(:@cached_changed_attributes) if defined?(@cached_changed_attributes)
104
- end
102
+ def clear_changed_attributes_cache
103
+ remove_instance_variable(:@cached_changed_attributes) if defined?(@cached_changed_attributes)
104
+ end
105
105
  end
106
106
  end
107
107
  end