activemodel 7.1.1 → 7.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +69 -0
- data/lib/active_model/attribute.rb +3 -3
- data/lib/active_model/attribute_methods.rb +41 -19
- data/lib/active_model/attribute_set.rb +1 -1
- data/lib/active_model/attributes.rb +3 -3
- data/lib/active_model/dirty.rb +1 -1
- data/lib/active_model/errors.rb +26 -0
- data/lib/active_model/gem_version.rb +1 -1
- data/lib/active_model/model.rb +8 -0
- data/lib/active_model/type/helpers/numeric.rb +2 -1
- data/lib/active_model/validations/validates.rb +1 -1
- data/lib/active_model.rb +1 -1
- metadata +11 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 47edf9505c3471e453e228f0f5df53f81f4ef35f124245e2fa3fe21a4fe98e83
|
|
4
|
+
data.tar.gz: 4c693d298afbfed8f0cd722d33f2426e0f3edb7305bb581e0c4ee2a3fa1203b1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 59b03357543036b2856fdec81f20ae784e4af91a5229caa9651ca689e1d62b85a5a1cb27a1767ce7865535344f986c7c2759f3efbf31a0665e13da5b53831dcd
|
|
7
|
+
data.tar.gz: 1a1a03cf6c4ed8f6d3f6462a9037a6d56343accb8c1aaf39e4320f32b359fe2f14339b498b67e2a59c1be1f796bcbee79ad36641bbefac22542f10597d8b2751
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,72 @@
|
|
|
1
|
+
## Rails 7.1.5 (October 30, 2024) ##
|
|
2
|
+
|
|
3
|
+
* Fix regression in `alias_attribute` to work with user defined methods.
|
|
4
|
+
|
|
5
|
+
`alias_attribute` would wrongly assume the attribute accessor was generated by Active Model.
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
class Person
|
|
9
|
+
include ActiveModel::AttributeMethods
|
|
10
|
+
|
|
11
|
+
define_attribute_methods :name
|
|
12
|
+
attr_accessor :name
|
|
13
|
+
|
|
14
|
+
alias_attribute :full_name, :name
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
person.full_name # => NoMethodError: undefined method `attribute' for an instance of Person
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
*Jean Boussier*
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
## Rails 7.1.4.2 (October 23, 2024) ##
|
|
24
|
+
|
|
25
|
+
* No changes.
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
## Rails 7.1.4.1 (October 15, 2024) ##
|
|
29
|
+
|
|
30
|
+
* No changes.
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
## Rails 7.1.4 (August 22, 2024) ##
|
|
34
|
+
|
|
35
|
+
* No changes.
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
## Rails 7.1.3.4 (June 04, 2024) ##
|
|
39
|
+
|
|
40
|
+
* No changes.
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
## Rails 7.1.3.3 (May 16, 2024) ##
|
|
44
|
+
|
|
45
|
+
* No changes.
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
## Rails 7.1.3.2 (February 21, 2024) ##
|
|
49
|
+
|
|
50
|
+
* No changes.
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
## Rails 7.1.3.1 (February 21, 2024) ##
|
|
54
|
+
|
|
55
|
+
* No changes.
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
## Rails 7.1.3 (January 16, 2024) ##
|
|
59
|
+
|
|
60
|
+
* No changes.
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
## Rails 7.1.2 (November 10, 2023) ##
|
|
64
|
+
|
|
65
|
+
* Make `==(other)` method of AttributeSet safe.
|
|
66
|
+
|
|
67
|
+
*Dmitry Pogrebnoy*
|
|
68
|
+
|
|
69
|
+
|
|
1
70
|
## Rails 7.1.1 (October 11, 2023) ##
|
|
2
71
|
|
|
3
72
|
* No changes.
|
|
@@ -178,11 +178,11 @@ module ActiveModel
|
|
|
178
178
|
def forgetting_assignment
|
|
179
179
|
# If this attribute was not persisted (with a `value_for_database`
|
|
180
180
|
# that might differ from `value_before_type_cast`) and `value` has not
|
|
181
|
-
# changed in place, we can
|
|
182
|
-
# deserialize / cast / serialize calls from computing the new
|
|
181
|
+
# changed in place, we can use the existing `value_before_type_cast`
|
|
182
|
+
# to avoid deserialize / cast / serialize calls from computing the new
|
|
183
183
|
# attribute's `value_before_type_cast`.
|
|
184
184
|
if !defined?(@value_for_database) && !changed_in_place?
|
|
185
|
-
|
|
185
|
+
with_value_from_database(value_before_type_cast)
|
|
186
186
|
else
|
|
187
187
|
super
|
|
188
188
|
end
|
|
@@ -215,9 +215,12 @@ module ActiveModel
|
|
|
215
215
|
end
|
|
216
216
|
end
|
|
217
217
|
|
|
218
|
-
def generate_alias_attribute_methods(code_generator, new_name, old_name)
|
|
219
|
-
|
|
220
|
-
|
|
218
|
+
def generate_alias_attribute_methods(code_generator, new_name, old_name) # :nodoc:
|
|
219
|
+
ActiveSupport::CodeGenerator.batch(code_generator, __FILE__, __LINE__) do |owner|
|
|
220
|
+
attribute_method_patterns.each do |pattern|
|
|
221
|
+
alias_attribute_method_definition(code_generator, pattern, new_name, old_name)
|
|
222
|
+
end
|
|
223
|
+
attribute_method_patterns_cache.clear
|
|
221
224
|
end
|
|
222
225
|
end
|
|
223
226
|
|
|
@@ -231,7 +234,7 @@ module ActiveModel
|
|
|
231
234
|
mangled_name = "__temp__#{target_name.unpack1("h*")}"
|
|
232
235
|
end
|
|
233
236
|
|
|
234
|
-
code_generator.define_cached_method(
|
|
237
|
+
code_generator.define_cached_method(mangled_name, as: method_name, namespace: :alias_attribute) do |batch|
|
|
235
238
|
body = if CALL_COMPILABLE_REGEXP.match?(target_name)
|
|
236
239
|
"self.#{target_name}(#{parameters || ''})"
|
|
237
240
|
else
|
|
@@ -321,25 +324,44 @@ module ActiveModel
|
|
|
321
324
|
# person.name = 'Bob'
|
|
322
325
|
# person.name # => "Bob"
|
|
323
326
|
# person.name_short? # => true
|
|
324
|
-
def define_attribute_method(attr_name, _owner: generated_attribute_methods)
|
|
327
|
+
def define_attribute_method(attr_name, _owner: generated_attribute_methods, as: attr_name)
|
|
325
328
|
ActiveSupport::CodeGenerator.batch(_owner, __FILE__, __LINE__) do |owner|
|
|
326
329
|
attribute_method_patterns.each do |pattern|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
unless instance_method_already_implemented?(method_name)
|
|
330
|
-
generate_method = "define_method_#{pattern.proxy_target}"
|
|
331
|
-
|
|
332
|
-
if respond_to?(generate_method, true)
|
|
333
|
-
send(generate_method, attr_name.to_s, owner: owner)
|
|
334
|
-
else
|
|
335
|
-
define_proxy_call(owner, method_name, pattern.proxy_target, pattern.parameters, attr_name.to_s, namespace: :active_model_proxy)
|
|
336
|
-
end
|
|
337
|
-
end
|
|
330
|
+
define_attribute_method_pattern(pattern, attr_name, owner: owner, as: as)
|
|
338
331
|
end
|
|
339
332
|
attribute_method_patterns_cache.clear
|
|
340
333
|
end
|
|
341
334
|
end
|
|
342
335
|
|
|
336
|
+
def define_attribute_method_pattern(pattern, attr_name, owner:, as:, override: false) # :nodoc:
|
|
337
|
+
canonical_method_name = pattern.method_name(attr_name)
|
|
338
|
+
public_method_name = pattern.method_name(as)
|
|
339
|
+
|
|
340
|
+
# If defining a regular attribute method, we don't override methods that are explictly
|
|
341
|
+
# defined in parrent classes.
|
|
342
|
+
if instance_method_already_implemented?(public_method_name)
|
|
343
|
+
# However, for `alias_attribute`, we always define the method.
|
|
344
|
+
# We check for override second because `instance_method_already_implemented?`
|
|
345
|
+
# also check for dangerous methods.
|
|
346
|
+
return unless override
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
generate_method = "define_method_#{pattern.proxy_target}"
|
|
350
|
+
if respond_to?(generate_method, true)
|
|
351
|
+
send(generate_method, attr_name.to_s, owner: owner, as: as)
|
|
352
|
+
else
|
|
353
|
+
define_proxy_call(
|
|
354
|
+
owner,
|
|
355
|
+
canonical_method_name,
|
|
356
|
+
pattern.proxy_target,
|
|
357
|
+
pattern.parameters,
|
|
358
|
+
attr_name.to_s,
|
|
359
|
+
namespace: :active_model_proxy,
|
|
360
|
+
as: public_method_name,
|
|
361
|
+
)
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
|
|
343
365
|
# Removes all the previously dynamically defined methods from the class, including alias attribute methods.
|
|
344
366
|
#
|
|
345
367
|
# class Person
|
|
@@ -418,7 +440,7 @@ module ActiveModel
|
|
|
418
440
|
# Define a method `name` in `mod` that dispatches to `send`
|
|
419
441
|
# using the given `extra` args. This falls back on `send`
|
|
420
442
|
# if the called name cannot be compiled.
|
|
421
|
-
def define_proxy_call(code_generator, name, proxy_target, parameters, *call_args, namespace:)
|
|
443
|
+
def define_proxy_call(code_generator, name, proxy_target, parameters, *call_args, namespace:, as: name)
|
|
422
444
|
mangled_name = name
|
|
423
445
|
unless NAME_COMPILABLE_REGEXP.match?(name)
|
|
424
446
|
mangled_name = "__temp__#{name.unpack1("h*")}"
|
|
@@ -426,9 +448,9 @@ module ActiveModel
|
|
|
426
448
|
|
|
427
449
|
call_args.map!(&:inspect)
|
|
428
450
|
call_args << parameters if parameters
|
|
429
|
-
namespace = :"#{namespace}_#{proxy_target}
|
|
451
|
+
namespace = :"#{namespace}_#{proxy_target}"
|
|
430
452
|
|
|
431
|
-
code_generator.define_cached_method(
|
|
453
|
+
code_generator.define_cached_method(mangled_name, as: as, namespace: namespace) do |batch|
|
|
432
454
|
body = if CALL_COMPILABLE_REGEXP.match?(proxy_target)
|
|
433
455
|
"self.#{proxy_target}(#{call_args.join(", ")})"
|
|
434
456
|
else
|
|
@@ -76,11 +76,11 @@ module ActiveModel
|
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
private
|
|
79
|
-
def define_method_attribute=(
|
|
79
|
+
def define_method_attribute=(canonical_name, owner:, as: canonical_name)
|
|
80
80
|
ActiveModel::AttributeMethods::AttrNames.define_attribute_accessor_method(
|
|
81
|
-
owner,
|
|
81
|
+
owner, canonical_name, writer: true,
|
|
82
82
|
) do |temp_method_name, attr_name_expr|
|
|
83
|
-
owner.define_cached_method("#{
|
|
83
|
+
owner.define_cached_method(temp_method_name, as: "#{as}=", namespace: :active_model) do |batch|
|
|
84
84
|
batch <<
|
|
85
85
|
"def #{temp_method_name}(value)" <<
|
|
86
86
|
" _write_attribute(#{attr_name_expr}, value)" <<
|
data/lib/active_model/dirty.rb
CHANGED
data/lib/active_model/errors.rb
CHANGED
|
@@ -63,6 +63,7 @@ module ActiveModel
|
|
|
63
63
|
|
|
64
64
|
extend Forwardable
|
|
65
65
|
|
|
66
|
+
##
|
|
66
67
|
# :method: each
|
|
67
68
|
#
|
|
68
69
|
# :call-seq: each(&block)
|
|
@@ -74,6 +75,31 @@ module ActiveModel
|
|
|
74
75
|
# # Will yield <#ActiveModel::Error attribute=name, type=too_short,
|
|
75
76
|
# options={:count=>3}>
|
|
76
77
|
# end
|
|
78
|
+
|
|
79
|
+
##
|
|
80
|
+
# :method: clear
|
|
81
|
+
#
|
|
82
|
+
# :call-seq: clear
|
|
83
|
+
#
|
|
84
|
+
# Clears all errors. Clearing the errors does not, however, make the model
|
|
85
|
+
# valid. The next time the validations are run (for example, via
|
|
86
|
+
# ActiveRecord::Validations#valid?), the errors collection will be filled
|
|
87
|
+
# again if any validations fail.
|
|
88
|
+
|
|
89
|
+
##
|
|
90
|
+
# :method: empty?
|
|
91
|
+
#
|
|
92
|
+
# :call-seq: empty?
|
|
93
|
+
#
|
|
94
|
+
# Returns true if there are no errors.
|
|
95
|
+
|
|
96
|
+
##
|
|
97
|
+
# :method: size
|
|
98
|
+
#
|
|
99
|
+
# :call-seq: size
|
|
100
|
+
#
|
|
101
|
+
# Returns number of errors.
|
|
102
|
+
|
|
77
103
|
def_delegators :@errors, :each, :clear, :empty?, :size, :uniq!
|
|
78
104
|
|
|
79
105
|
# The actual array of +Error+ objects
|
data/lib/active_model/model.rb
CHANGED
|
@@ -52,6 +52,10 @@ module ActiveModel
|
|
|
52
52
|
# Returns a hash of the given methods with their names as keys and returned
|
|
53
53
|
# values as values.
|
|
54
54
|
#
|
|
55
|
+
# person = Person.new(id: 1, name: "bob")
|
|
56
|
+
# person.slice(:id, :name)
|
|
57
|
+
# => { "id" => 1, "name" => "bob" }
|
|
58
|
+
#
|
|
55
59
|
#--
|
|
56
60
|
# Implemented by ActiveModel::Access#slice.
|
|
57
61
|
|
|
@@ -62,6 +66,10 @@ module ActiveModel
|
|
|
62
66
|
#
|
|
63
67
|
# Returns an array of the values returned by the given methods.
|
|
64
68
|
#
|
|
69
|
+
# person = Person.new(id: 1, name: "bob")
|
|
70
|
+
# person.values_at(:id, :name)
|
|
71
|
+
# => [1, "bob"]
|
|
72
|
+
#
|
|
65
73
|
#--
|
|
66
74
|
# Implemented by ActiveModel::Access#values_at.
|
|
67
75
|
end
|
|
@@ -42,7 +42,8 @@ module ActiveModel
|
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
def number_to_non_number?(old_value, new_value_before_type_cast)
|
|
45
|
-
old_value != nil &&
|
|
45
|
+
old_value != nil && !new_value_before_type_cast.is_a?(::Numeric) &&
|
|
46
|
+
non_numeric_string?(new_value_before_type_cast.to_s)
|
|
46
47
|
end
|
|
47
48
|
|
|
48
49
|
def non_numeric_string?(value)
|
|
@@ -10,7 +10,7 @@ module ActiveModel
|
|
|
10
10
|
# validators can be overridden inside specific classes by creating
|
|
11
11
|
# custom validator classes in their place such as PresenceValidator.
|
|
12
12
|
#
|
|
13
|
-
# Examples of using the default
|
|
13
|
+
# Examples of using the default \Rails validators:
|
|
14
14
|
#
|
|
15
15
|
# validates :username, absence: true
|
|
16
16
|
# validates :terms, acceptance: true
|
data/lib/active_model.rb
CHANGED
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: 7.1.
|
|
4
|
+
version: 7.1.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Heinemeier Hansson
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2024-10-31 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: 7.1.
|
|
19
|
+
version: 7.1.5
|
|
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: 7.1.
|
|
26
|
+
version: 7.1.5
|
|
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.
|
|
@@ -112,12 +112,12 @@ licenses:
|
|
|
112
112
|
- MIT
|
|
113
113
|
metadata:
|
|
114
114
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
|
115
|
-
changelog_uri: https://github.com/rails/rails/blob/v7.1.
|
|
116
|
-
documentation_uri: https://api.rubyonrails.org/v7.1.
|
|
115
|
+
changelog_uri: https://github.com/rails/rails/blob/v7.1.5/activemodel/CHANGELOG.md
|
|
116
|
+
documentation_uri: https://api.rubyonrails.org/v7.1.5/
|
|
117
117
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
|
118
|
-
source_code_uri: https://github.com/rails/rails/tree/v7.1.
|
|
118
|
+
source_code_uri: https://github.com/rails/rails/tree/v7.1.5/activemodel
|
|
119
119
|
rubygems_mfa_required: 'true'
|
|
120
|
-
post_install_message:
|
|
120
|
+
post_install_message:
|
|
121
121
|
rdoc_options: []
|
|
122
122
|
require_paths:
|
|
123
123
|
- lib
|
|
@@ -132,8 +132,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
132
132
|
- !ruby/object:Gem::Version
|
|
133
133
|
version: '0'
|
|
134
134
|
requirements: []
|
|
135
|
-
rubygems_version: 3.
|
|
136
|
-
signing_key:
|
|
135
|
+
rubygems_version: 3.5.16
|
|
136
|
+
signing_key:
|
|
137
137
|
specification_version: 4
|
|
138
138
|
summary: A toolkit for building modeling frameworks (part of Rails).
|
|
139
139
|
test_files: []
|