activemodel 5.2.0.rc1 → 5.2.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.rdoc +1 -1
- data/lib/active_model/attribute_assignment.rb +2 -0
- data/lib/active_model/attribute_mutation_tracker.rb +3 -4
- data/lib/active_model/attribute_set/builder.rb +11 -9
- data/lib/active_model/attributes.rb +4 -0
- data/lib/active_model/dirty.rb +69 -39
- data/lib/active_model/gem_version.rb +1 -1
- data/lib/active_model/serialization.rb +1 -1
- data/lib/active_model/type/date.rb +1 -1
- data/lib/active_model/type/time.rb +2 -6
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 97b6d1fb9b61ef956d88c6ee764394e9ccc0fcad2333073a876066fd9c7fcb7a
|
4
|
+
data.tar.gz: 86e60a71d98b585c900c3351a4c4fcf1f16ac73e4c0fc0b4595a443733c31f50
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d11a69342faac6bed87647ec40059830c8441459f30a6c9d94f3656ff2ce89a08fe3b12eed6846bae3352eb5fb929d4e30ab91611e569e7dae5f9e851fe47ba
|
7
|
+
data.tar.gz: 3493c445e4a3db83fcad5b043a82d16cf1242286bd49e73755bebf82a17f6b0f8f78d9563d2eac7d6ba739dc921b8a9a8a9ce2108098e4aab72bfa335658feec
|
data/CHANGELOG.md
CHANGED
data/README.rdoc
CHANGED
@@ -239,7 +239,7 @@ The latest version of Active Model can be installed with RubyGems:
|
|
239
239
|
|
240
240
|
Source code can be downloaded as part of the Rails project on GitHub
|
241
241
|
|
242
|
-
* https://github.com/rails/rails/tree/
|
242
|
+
* https://github.com/rails/rails/tree/5-2-stable/activemodel
|
243
243
|
|
244
244
|
|
245
245
|
== License
|
@@ -35,10 +35,6 @@ module ActiveModel
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
def changed_attribute_names
|
39
|
-
attr_names.select { |attr| changed?(attr) }
|
40
|
-
end
|
41
|
-
|
42
38
|
def any_changes?
|
43
39
|
attr_names.any? { |attr| changed?(attr) }
|
44
40
|
end
|
@@ -113,5 +109,8 @@ module ActiveModel
|
|
113
109
|
|
114
110
|
def original_value(*)
|
115
111
|
end
|
112
|
+
|
113
|
+
def force_change(*)
|
114
|
+
end
|
116
115
|
end
|
117
116
|
end
|
@@ -22,12 +22,12 @@ module ActiveModel
|
|
22
22
|
class LazyAttributeHash # :nodoc:
|
23
23
|
delegate :transform_values, :each_key, :each_value, :fetch, :except, to: :materialize
|
24
24
|
|
25
|
-
def initialize(types, values, additional_types, default_attributes)
|
25
|
+
def initialize(types, values, additional_types, default_attributes, delegate_hash = {})
|
26
26
|
@types = types
|
27
27
|
@values = values
|
28
28
|
@additional_types = additional_types
|
29
29
|
@materialized = false
|
30
|
-
@delegate_hash =
|
30
|
+
@delegate_hash = delegate_hash
|
31
31
|
@default_attributes = default_attributes
|
32
32
|
end
|
33
33
|
|
@@ -76,15 +76,17 @@ module ActiveModel
|
|
76
76
|
end
|
77
77
|
|
78
78
|
def marshal_dump
|
79
|
-
|
79
|
+
[@types, @values, @additional_types, @default_attributes, @delegate_hash]
|
80
80
|
end
|
81
81
|
|
82
|
-
def marshal_load(
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
82
|
+
def marshal_load(values)
|
83
|
+
if values.is_a?(Hash)
|
84
|
+
empty_hash = {}.freeze
|
85
|
+
initialize(empty_hash, empty_hash, empty_hash, empty_hash, values)
|
86
|
+
@materialized = true
|
87
|
+
else
|
88
|
+
initialize(*values)
|
89
|
+
end
|
88
90
|
end
|
89
91
|
|
90
92
|
protected
|
data/lib/active_model/dirty.rb
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
require "active_support/hash_with_indifferent_access"
|
4
4
|
require "active_support/core_ext/object/duplicable"
|
5
5
|
require "active_model/attribute_mutation_tracker"
|
6
|
-
require "active_model/attribute_set"
|
7
6
|
|
8
7
|
module ActiveModel
|
9
8
|
# == Active \Model \Dirty
|
@@ -143,8 +142,11 @@ module ActiveModel
|
|
143
142
|
end
|
144
143
|
|
145
144
|
def changes_applied # :nodoc:
|
146
|
-
|
145
|
+
unless defined?(@attributes)
|
146
|
+
@previously_changed = changes
|
147
|
+
end
|
147
148
|
@mutations_before_last_save = mutations_from_database
|
149
|
+
@attributes_changed_by_setter = ActiveSupport::HashWithIndifferentAccess.new
|
148
150
|
forget_attribute_assignments
|
149
151
|
@mutations_from_database = nil
|
150
152
|
end
|
@@ -155,7 +157,7 @@ module ActiveModel
|
|
155
157
|
# person.name = 'bob'
|
156
158
|
# person.changed? # => true
|
157
159
|
def changed?
|
158
|
-
|
160
|
+
changed_attributes.present?
|
159
161
|
end
|
160
162
|
|
161
163
|
# Returns an array with the name of the attributes with unsaved changes.
|
@@ -164,24 +166,24 @@ module ActiveModel
|
|
164
166
|
# person.name = 'bob'
|
165
167
|
# person.changed # => ["name"]
|
166
168
|
def changed
|
167
|
-
|
169
|
+
changed_attributes.keys
|
168
170
|
end
|
169
171
|
|
170
172
|
# Handles <tt>*_changed?</tt> for +method_missing+.
|
171
173
|
def attribute_changed?(attr, from: OPTION_NOT_GIVEN, to: OPTION_NOT_GIVEN) # :nodoc:
|
172
|
-
!!
|
174
|
+
!!changes_include?(attr) &&
|
173
175
|
(to == OPTION_NOT_GIVEN || to == _read_attribute(attr)) &&
|
174
|
-
(from == OPTION_NOT_GIVEN || from ==
|
176
|
+
(from == OPTION_NOT_GIVEN || from == changed_attributes[attr])
|
175
177
|
end
|
176
178
|
|
177
179
|
# Handles <tt>*_was</tt> for +method_missing+.
|
178
180
|
def attribute_was(attr) # :nodoc:
|
179
|
-
|
181
|
+
attribute_changed?(attr) ? changed_attributes[attr] : _read_attribute(attr)
|
180
182
|
end
|
181
183
|
|
182
184
|
# Handles <tt>*_previously_changed?</tt> for +method_missing+.
|
183
185
|
def attribute_previously_changed?(attr) #:nodoc:
|
184
|
-
|
186
|
+
previous_changes_include?(attr)
|
185
187
|
end
|
186
188
|
|
187
189
|
# Restore all previous data of the provided attributes.
|
@@ -191,12 +193,15 @@ module ActiveModel
|
|
191
193
|
|
192
194
|
# Clears all dirty data: current changes and previous changes.
|
193
195
|
def clear_changes_information
|
196
|
+
@previously_changed = ActiveSupport::HashWithIndifferentAccess.new
|
194
197
|
@mutations_before_last_save = nil
|
198
|
+
@attributes_changed_by_setter = ActiveSupport::HashWithIndifferentAccess.new
|
195
199
|
forget_attribute_assignments
|
196
200
|
@mutations_from_database = nil
|
197
201
|
end
|
198
202
|
|
199
203
|
def clear_attribute_changes(attr_names)
|
204
|
+
attributes_changed_by_setter.except!(*attr_names)
|
200
205
|
attr_names.each do |attr_name|
|
201
206
|
clear_attribute_change(attr_name)
|
202
207
|
end
|
@@ -209,7 +214,13 @@ module ActiveModel
|
|
209
214
|
# person.name = 'robert'
|
210
215
|
# person.changed_attributes # => {"name" => "bob"}
|
211
216
|
def changed_attributes
|
212
|
-
|
217
|
+
# This should only be set by methods which will call changed_attributes
|
218
|
+
# multiple times when it is known that the computed value cannot change.
|
219
|
+
if defined?(@cached_changed_attributes)
|
220
|
+
@cached_changed_attributes
|
221
|
+
else
|
222
|
+
attributes_changed_by_setter.reverse_merge(mutations_from_database.changed_values).freeze
|
223
|
+
end
|
213
224
|
end
|
214
225
|
|
215
226
|
# Returns a hash of changed attributes indicating their original
|
@@ -219,8 +230,9 @@ module ActiveModel
|
|
219
230
|
# person.name = 'bob'
|
220
231
|
# person.changes # => { "name" => ["bill", "bob"] }
|
221
232
|
def changes
|
222
|
-
|
223
|
-
|
233
|
+
cache_changed_attributes do
|
234
|
+
ActiveSupport::HashWithIndifferentAccess[changed.map { |attr| [attr, attribute_change(attr)] }]
|
235
|
+
end
|
224
236
|
end
|
225
237
|
|
226
238
|
# Returns a hash of attributes that were changed before the model was saved.
|
@@ -230,7 +242,8 @@ module ActiveModel
|
|
230
242
|
# person.save
|
231
243
|
# person.previous_changes # => {"name" => ["bob", "robert"]}
|
232
244
|
def previous_changes
|
233
|
-
|
245
|
+
@previously_changed ||= ActiveSupport::HashWithIndifferentAccess.new
|
246
|
+
@previously_changed.merge(mutations_before_last_save.changes)
|
234
247
|
end
|
235
248
|
|
236
249
|
def attribute_changed_in_place?(attr_name) # :nodoc:
|
@@ -246,17 +259,11 @@ module ActiveModel
|
|
246
259
|
unless defined?(@mutations_from_database)
|
247
260
|
@mutations_from_database = nil
|
248
261
|
end
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
Hash.new { |h, attr|
|
254
|
-
h[attr] = Attribute.with_cast_value(attr, _clone_attribute(attr), Type.default_value)
|
255
|
-
}
|
256
|
-
)
|
262
|
+
@mutations_from_database ||= if defined?(@attributes)
|
263
|
+
ActiveModel::AttributeMutationTracker.new(@attributes)
|
264
|
+
else
|
265
|
+
NullMutationTracker.instance
|
257
266
|
end
|
258
|
-
|
259
|
-
@mutations_from_database ||= ActiveModel::AttributeMutationTracker.new(@attributes)
|
260
267
|
end
|
261
268
|
|
262
269
|
def forget_attribute_assignments
|
@@ -267,45 +274,68 @@ module ActiveModel
|
|
267
274
|
@mutations_before_last_save ||= ActiveModel::NullMutationTracker.instance
|
268
275
|
end
|
269
276
|
|
277
|
+
def cache_changed_attributes
|
278
|
+
@cached_changed_attributes = changed_attributes
|
279
|
+
yield
|
280
|
+
ensure
|
281
|
+
clear_changed_attributes_cache
|
282
|
+
end
|
283
|
+
|
284
|
+
def clear_changed_attributes_cache
|
285
|
+
remove_instance_variable(:@cached_changed_attributes) if defined?(@cached_changed_attributes)
|
286
|
+
end
|
287
|
+
|
288
|
+
# Returns +true+ if attr_name is changed, +false+ otherwise.
|
289
|
+
def changes_include?(attr_name)
|
290
|
+
attributes_changed_by_setter.include?(attr_name) || mutations_from_database.changed?(attr_name)
|
291
|
+
end
|
292
|
+
alias attribute_changed_by_setter? changes_include?
|
293
|
+
|
294
|
+
# Returns +true+ if attr_name were changed before the model was saved,
|
295
|
+
# +false+ otherwise.
|
296
|
+
def previous_changes_include?(attr_name)
|
297
|
+
previous_changes.include?(attr_name)
|
298
|
+
end
|
299
|
+
|
270
300
|
# Handles <tt>*_change</tt> for +method_missing+.
|
271
301
|
def attribute_change(attr)
|
272
|
-
[
|
302
|
+
[changed_attributes[attr], _read_attribute(attr)] if attribute_changed?(attr)
|
273
303
|
end
|
274
304
|
|
275
305
|
# Handles <tt>*_previous_change</tt> for +method_missing+.
|
276
306
|
def attribute_previous_change(attr)
|
277
|
-
|
307
|
+
previous_changes[attr] if attribute_previously_changed?(attr)
|
278
308
|
end
|
279
309
|
|
280
310
|
# Handles <tt>*_will_change!</tt> for +method_missing+.
|
281
311
|
def attribute_will_change!(attr)
|
282
|
-
|
283
|
-
|
284
|
-
|
312
|
+
unless attribute_changed?(attr)
|
313
|
+
begin
|
314
|
+
value = _read_attribute(attr)
|
315
|
+
value = value.duplicable? ? value.clone : value
|
316
|
+
rescue TypeError, NoMethodError
|
317
|
+
end
|
318
|
+
|
319
|
+
set_attribute_was(attr, value)
|
285
320
|
end
|
321
|
+
mutations_from_database.force_change(attr)
|
286
322
|
end
|
287
323
|
|
288
324
|
# Handles <tt>restore_*!</tt> for +method_missing+.
|
289
325
|
def restore_attribute!(attr)
|
290
326
|
if attribute_changed?(attr)
|
291
|
-
__send__("#{attr}=",
|
327
|
+
__send__("#{attr}=", changed_attributes[attr])
|
292
328
|
clear_attribute_changes([attr])
|
293
329
|
end
|
294
330
|
end
|
295
331
|
|
296
|
-
def
|
297
|
-
|
298
|
-
changed.each do |attr|
|
299
|
-
@attributes.write_from_user(attr, _read_attribute(attr))
|
300
|
-
end
|
301
|
-
end
|
332
|
+
def attributes_changed_by_setter
|
333
|
+
@attributes_changed_by_setter ||= ActiveSupport::HashWithIndifferentAccess.new
|
302
334
|
end
|
303
335
|
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
rescue TypeError, NoMethodError
|
308
|
-
value
|
336
|
+
# Force an attribute to have a particular "before" value
|
337
|
+
def set_attribute_was(attr, old_value)
|
338
|
+
attributes_changed_by_setter[attr] = old_value
|
309
339
|
end
|
310
340
|
end
|
311
341
|
end
|
@@ -179,7 +179,7 @@ module ActiveModel
|
|
179
179
|
return unless includes = options[:include]
|
180
180
|
|
181
181
|
unless includes.is_a?(Hash)
|
182
|
-
includes = Hash[Array(includes).
|
182
|
+
includes = Hash[Array(includes).flat_map { |n| n.is_a?(Hash) ? n.to_a : [[n, {}]] }]
|
183
183
|
end
|
184
184
|
|
185
185
|
includes.each do |association, opts|
|
@@ -28,14 +28,10 @@ module ActiveModel
|
|
28
28
|
private
|
29
29
|
|
30
30
|
def cast_value(value)
|
31
|
-
return value unless value.is_a?(::String)
|
31
|
+
return apply_seconds_precision(value) unless value.is_a?(::String)
|
32
32
|
return if value.empty?
|
33
33
|
|
34
|
-
|
35
|
-
dummy_time_value = value
|
36
|
-
else
|
37
|
-
dummy_time_value = "2000-01-01 #{value}"
|
38
|
-
end
|
34
|
+
dummy_time_value = value.sub(/\A(\d\d\d\d-\d\d-\d\d |)/, "2000-01-01 ")
|
39
35
|
|
40
36
|
fast_string_to_time(dummy_time_value) || begin
|
41
37
|
time_hash = ::Date._parse(dummy_time_value)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activemodel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.2.0.
|
4
|
+
version: 5.2.0.rc2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-03-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 5.2.0.
|
19
|
+
version: 5.2.0.rc2
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 5.2.0.
|
26
|
+
version: 5.2.0.rc2
|
27
27
|
description: A toolkit for building modeling frameworks like Active Record. Rich support
|
28
28
|
for attributes, callbacks, validations, serialization, internationalization, and
|
29
29
|
testing.
|
@@ -100,8 +100,8 @@ homepage: http://rubyonrails.org
|
|
100
100
|
licenses:
|
101
101
|
- MIT
|
102
102
|
metadata:
|
103
|
-
source_code_uri: https://github.com/rails/rails/tree/v5.2.0.
|
104
|
-
changelog_uri: https://github.com/rails/rails/blob/v5.2.0.
|
103
|
+
source_code_uri: https://github.com/rails/rails/tree/v5.2.0.rc2/activemodel
|
104
|
+
changelog_uri: https://github.com/rails/rails/blob/v5.2.0.rc2/activemodel/CHANGELOG.md
|
105
105
|
post_install_message:
|
106
106
|
rdoc_options: []
|
107
107
|
require_paths:
|
@@ -118,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
118
118
|
version: 1.3.1
|
119
119
|
requirements: []
|
120
120
|
rubyforge_project:
|
121
|
-
rubygems_version: 2.7.
|
121
|
+
rubygems_version: 2.7.6
|
122
122
|
signing_key:
|
123
123
|
specification_version: 4
|
124
124
|
summary: A toolkit for building modeling frameworks (part of Rails).
|