activemodel 8.1.3.1 → 8.1.4
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 +38 -0
- data/lib/active_model/attribute_methods.rb +10 -2
- data/lib/active_model/attributes/normalization.rb +6 -1
- data/lib/active_model/dirty.rb +1 -1
- data/lib/active_model/errors.rb +2 -1
- data/lib/active_model/gem_version.rb +2 -2
- data/lib/active_model/serialization.rb +3 -1
- data/lib/active_model/serializers/json.rb +1 -1
- data/lib/active_model/type/date_time.rb +2 -5
- data/lib/active_model/type/decimal.rb +1 -1
- data/lib/active_model/type/integer.rb +9 -1
- data/lib/active_model/validations/validates.rb +1 -1
- data/lib/active_model/validations.rb +5 -3
- 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: 37ac49fcbb7194fa33c83ce420982403b8f1bcd5059e0e893a7758a2f7b1fa0f
|
|
4
|
+
data.tar.gz: 2f41f78730b71f3b386299fa207176cd7c477badf17917f9a540aa55397996fd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1cd37e1b7ed1206d74e7dc170a51a4641b9152056aa367eadb37d3315693b0ebe6b7814e391fdefaa7f3e29988c1a0aa594c3faf14990797ba1e972c5e99ffd1
|
|
7
|
+
data.tar.gz: 5720c98d3ddeb1aeb18caccd209d9ae3fe57a8b2995849f3876514e6e0c2ada90a401f9ac2caf8a17e4d9c49850729fd2e19c0358834d281086117c7b916baae
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,41 @@
|
|
|
1
|
+
## Rails 8.1.4 (September 24, 2026) ##
|
|
2
|
+
|
|
3
|
+
* Fix `ActiveModel::Errors#import` mutating the override options hash passed to it.
|
|
4
|
+
|
|
5
|
+
*Kenta Ishizaki*
|
|
6
|
+
|
|
7
|
+
* Fix `normalizes` not detecting in-place changes for attributes whose database
|
|
8
|
+
cast type differs from the attribute type (e.g. JSON columns), causing
|
|
9
|
+
normalization to be skipped on validation.
|
|
10
|
+
|
|
11
|
+
*Chedli Bourguiba*
|
|
12
|
+
|
|
13
|
+
* Fix `alias_attribute` accumulating duplicate entries in `aliases_by_attribute_name`
|
|
14
|
+
when called multiple times with the same arguments.
|
|
15
|
+
|
|
16
|
+
*Nicholas Jakobsen*
|
|
17
|
+
|
|
18
|
+
* Fix `normalizes` re-applying normalizations on every validation of an
|
|
19
|
+
unpersisted record, and speed up validation of normalized attributes.
|
|
20
|
+
|
|
21
|
+
The in-place mutation check re-ran the normalizer on every `valid?` of an
|
|
22
|
+
unpersisted record: wasteful for idempotent normalizers and compounded the
|
|
23
|
+
result for non-idempotent ones. Normalizations are now re-applied only on a
|
|
24
|
+
genuine in-place mutation.
|
|
25
|
+
|
|
26
|
+
*Yaroslav Markin*
|
|
27
|
+
|
|
28
|
+
* Limit the size of strings `ActiveModel::Type::Integer` will coerce with `to_i`.
|
|
29
|
+
|
|
30
|
+
Calling `to_i` on very long strings can take a long time and could be used as
|
|
31
|
+
a DoS vector. Integer casting now only considers the first `_limit * 4` bytes
|
|
32
|
+
of a string (16 bytes for a default 4-byte integer, 32 bytes for an 8-byte
|
|
33
|
+
bigint), which is enough to hold the maximum representable value plus a sign
|
|
34
|
+
or a short slug suffix.
|
|
35
|
+
|
|
36
|
+
*Aaron Patterson*, *Jean Boussier*
|
|
37
|
+
|
|
38
|
+
|
|
1
39
|
## Rails 8.1.3.1 (July 29, 2026) ##
|
|
2
40
|
|
|
3
41
|
* No changes.
|
|
@@ -204,7 +204,7 @@ module ActiveModel
|
|
|
204
204
|
old_name = old_name.to_s
|
|
205
205
|
new_name = new_name.to_s
|
|
206
206
|
self.attribute_aliases = attribute_aliases.merge(new_name => old_name)
|
|
207
|
-
aliases_by_attribute_name[old_name]
|
|
207
|
+
aliases_by_attribute_name[old_name] |= [new_name]
|
|
208
208
|
eagerly_generate_alias_attribute_methods(new_name, old_name)
|
|
209
209
|
end
|
|
210
210
|
|
|
@@ -521,10 +521,18 @@ module ActiveModel
|
|
|
521
521
|
__send__(match.proxy_target, match.attr_name, ...)
|
|
522
522
|
end
|
|
523
523
|
|
|
524
|
+
##
|
|
525
|
+
# :method: respond_to_without_attributes?
|
|
526
|
+
# :call-seq:
|
|
527
|
+
# respond_to_without_attributes?(method, include_private_methods = false)
|
|
528
|
+
#
|
|
529
|
+
# Checks whether the object responds to +method+ without searching the
|
|
530
|
+
# attributes.
|
|
531
|
+
define_method(:respond_to_without_attributes?, Kernel.instance_method(:respond_to?))
|
|
532
|
+
|
|
524
533
|
# A +Person+ instance with a +name+ attribute can ask
|
|
525
534
|
# <tt>person.respond_to?(:name)</tt>, <tt>person.respond_to?(:name=)</tt>,
|
|
526
535
|
# and <tt>person.respond_to?(:name?)</tt> which will all return +true+.
|
|
527
|
-
alias :respond_to_without_attributes? :respond_to?
|
|
528
536
|
def respond_to?(method, include_private_methods = false)
|
|
529
537
|
if super
|
|
530
538
|
true
|
|
@@ -139,10 +139,15 @@ module ActiveModel
|
|
|
139
139
|
private
|
|
140
140
|
def normalize_changed_in_place_attributes
|
|
141
141
|
self.class.normalized_attributes.each do |name|
|
|
142
|
-
|
|
142
|
+
attribute = @attributes[name.to_s]
|
|
143
|
+
normalize_attribute(name) if normalized_attribute_changed_in_place?(attribute)
|
|
143
144
|
end
|
|
144
145
|
end
|
|
145
146
|
|
|
147
|
+
def normalized_attribute_changed_in_place?(attribute)
|
|
148
|
+
attribute.changed_in_place? && attribute.value != attribute.type_cast(attribute.value_before_type_cast)
|
|
149
|
+
end
|
|
150
|
+
|
|
146
151
|
class NormalizedValueType < DelegateClass(ActiveModel::Type::Value) # :nodoc:
|
|
147
152
|
include ActiveModel::Type::SerializeCastValue
|
|
148
153
|
|
data/lib/active_model/dirty.rb
CHANGED
|
@@ -230,7 +230,7 @@ module ActiveModel
|
|
|
230
230
|
#
|
|
231
231
|
# This method is generated for each attribute.
|
|
232
232
|
#
|
|
233
|
-
# Clears
|
|
233
|
+
# Clears the current changes of the attribute.
|
|
234
234
|
#
|
|
235
235
|
# person = Person.new(name: 'Chris')
|
|
236
236
|
# person.name = 'Jason'
|
data/lib/active_model/errors.rb
CHANGED
|
@@ -149,6 +149,7 @@ module ActiveModel
|
|
|
149
149
|
# * +:attribute+ - Override the attribute the error belongs to.
|
|
150
150
|
# * +:type+ - Override type of the error.
|
|
151
151
|
def import(error, override_options = {})
|
|
152
|
+
override_options = override_options.dup
|
|
152
153
|
[:attribute, :type].each do |key|
|
|
153
154
|
if override_options.key?(key)
|
|
154
155
|
override_options[key] = override_options[key].to_sym
|
|
@@ -311,7 +312,7 @@ module ActiveModel
|
|
|
311
312
|
#
|
|
312
313
|
# person.errors.add(:name, :too_long, count: 25)
|
|
313
314
|
# person.errors.messages
|
|
314
|
-
# # => ["is too long (maximum is 25 characters)"]
|
|
315
|
+
# # => {:name=>["is too long (maximum is 25 characters)"]}
|
|
315
316
|
#
|
|
316
317
|
# If +type+ is a proc, it will be called, allowing for things like
|
|
317
318
|
# <tt>Time.now</tt> to be used within an error.
|
|
@@ -26,7 +26,7 @@ module ActiveModel
|
|
|
26
26
|
# user = User.find(1)
|
|
27
27
|
# user.as_json
|
|
28
28
|
# # => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
|
|
29
|
-
# # "created_at" => "2006-08-01T17:27:
|
|
29
|
+
# # "created_at" => "2006-08-01T17:27:13.000Z", "awesome" => true}
|
|
30
30
|
#
|
|
31
31
|
# ActiveRecord::Base.include_root_in_json = true
|
|
32
32
|
#
|
|
@@ -25,11 +25,8 @@ module ActiveModel
|
|
|
25
25
|
# event.start.sec # => 0
|
|
26
26
|
# event.start.zone # => "EAT"
|
|
27
27
|
#
|
|
28
|
-
# String values are parsed using the ISO 8601 datetime format.
|
|
29
|
-
# time
|
|
30
|
-
#
|
|
31
|
-
# event.start = "06:07:08+09:00"
|
|
32
|
-
# event.start.utc # => 1999-12-31 21:07:08 UTC
|
|
28
|
+
# String values are parsed using the ISO 8601 datetime format. Use the
|
|
29
|
+
# +:time+ type instead to parse partial time-only values.
|
|
33
30
|
#
|
|
34
31
|
# The degree of sub-second precision can be customized when declaring an
|
|
35
32
|
# attribute:
|
|
@@ -32,7 +32,7 @@ module ActiveModel
|
|
|
32
32
|
# bag.weight # => nil
|
|
33
33
|
#
|
|
34
34
|
# bag.weight = :arbitrary
|
|
35
|
-
# bag.weight # =>
|
|
35
|
+
# bag.weight # => 0.0 (the result of `.to_s.to_d`)
|
|
36
36
|
#
|
|
37
37
|
# Decimal precision defaults to 18, and can be customized when declaring an
|
|
38
38
|
# attribute:
|
|
@@ -110,7 +110,15 @@ module ActiveModel
|
|
|
110
110
|
end
|
|
111
111
|
|
|
112
112
|
def cast_value(value)
|
|
113
|
-
value
|
|
113
|
+
case value
|
|
114
|
+
when ::Integer
|
|
115
|
+
value
|
|
116
|
+
when ::String
|
|
117
|
+
str = value.bytesize > _limit * 4 ? value.byteslice(0, _limit * 4) : value
|
|
118
|
+
str.to_i rescue nil
|
|
119
|
+
else
|
|
120
|
+
value.to_i rescue nil
|
|
121
|
+
end
|
|
114
122
|
end
|
|
115
123
|
|
|
116
124
|
def max_value
|
|
@@ -80,7 +80,7 @@ module ActiveModel
|
|
|
80
80
|
# <tt>on: [:create, :custom_validation_context]</tt>)
|
|
81
81
|
# * <tt>:except_on</tt> - Specifies the contexts where this validation is not active.
|
|
82
82
|
# Runs in all validation contexts by default +nil+. You can pass a symbol
|
|
83
|
-
# or an array of symbols. (e.g. <tt>
|
|
83
|
+
# or an array of symbols. (e.g. <tt>except_on: :create</tt> or
|
|
84
84
|
# <tt>except_on: :custom_validation_context</tt> or
|
|
85
85
|
# <tt>except_on: [:create, :custom_validation_context]</tt>)
|
|
86
86
|
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine
|
|
@@ -72,7 +72,7 @@ module ActiveModel
|
|
|
72
72
|
# <tt>on: [:create, :custom_validation_context]</tt>)
|
|
73
73
|
# * <tt>:except_on</tt> - Specifies the contexts where this validation is not active.
|
|
74
74
|
# Runs in all validation contexts by default +nil+. You can pass a symbol
|
|
75
|
-
# or an array of symbols. (e.g. <tt>
|
|
75
|
+
# or an array of symbols. (e.g. <tt>except_on: :create</tt> or
|
|
76
76
|
# <tt>except_on: :custom_validation_context</tt> or
|
|
77
77
|
# <tt>except_on: [:create, :custom_validation_context]</tt>)
|
|
78
78
|
# * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+.
|
|
@@ -144,7 +144,7 @@ module ActiveModel
|
|
|
144
144
|
# <tt>on: [:create, :custom_validation_context]</tt>)
|
|
145
145
|
# * <tt>:except_on</tt> - Specifies the contexts where this validation is not active.
|
|
146
146
|
# Runs in all validation contexts by default +nil+. You can pass a symbol
|
|
147
|
-
# or an array of symbols. (e.g. <tt>
|
|
147
|
+
# or an array of symbols. (e.g. <tt>except_on: :create</tt> or
|
|
148
148
|
# <tt>except_on: :custom_validation_context</tt> or
|
|
149
149
|
# <tt>except_on: [:create, :custom_validation_context]</tt>)
|
|
150
150
|
# * <tt>:if</tt> - Specifies a method or proc to call to determine
|
|
@@ -436,7 +436,9 @@ module ActiveModel
|
|
|
436
436
|
# @data[key]
|
|
437
437
|
# end
|
|
438
438
|
# end
|
|
439
|
-
|
|
439
|
+
def read_attribute_for_validation(key)
|
|
440
|
+
send(key)
|
|
441
|
+
end
|
|
440
442
|
|
|
441
443
|
# Returns the context when running validations.
|
|
442
444
|
def validation_context
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activemodel
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 8.1.
|
|
4
|
+
version: 8.1.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Heinemeier Hansson
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 8.1.
|
|
18
|
+
version: 8.1.4
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - '='
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 8.1.
|
|
25
|
+
version: 8.1.4
|
|
26
26
|
description: A toolkit for building modeling frameworks like Active Record. Rich support
|
|
27
27
|
for attributes, callbacks, validations, serialization, internationalization, and
|
|
28
28
|
testing.
|
|
@@ -113,10 +113,10 @@ licenses:
|
|
|
113
113
|
- MIT
|
|
114
114
|
metadata:
|
|
115
115
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
|
116
|
-
changelog_uri: https://github.com/rails/rails/blob/v8.1.
|
|
117
|
-
documentation_uri: https://api.rubyonrails.org/v8.1.
|
|
116
|
+
changelog_uri: https://github.com/rails/rails/blob/v8.1.4/activemodel/CHANGELOG.md
|
|
117
|
+
documentation_uri: https://api.rubyonrails.org/v8.1.4/
|
|
118
118
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
|
119
|
-
source_code_uri: https://github.com/rails/rails/tree/v8.1.
|
|
119
|
+
source_code_uri: https://github.com/rails/rails/tree/v8.1.4/activemodel
|
|
120
120
|
rubygems_mfa_required: 'true'
|
|
121
121
|
rdoc_options: []
|
|
122
122
|
require_paths:
|
|
@@ -132,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
132
132
|
- !ruby/object:Gem::Version
|
|
133
133
|
version: '0'
|
|
134
134
|
requirements: []
|
|
135
|
-
rubygems_version: 4.0.
|
|
135
|
+
rubygems_version: 4.0.20
|
|
136
136
|
specification_version: 4
|
|
137
137
|
summary: A toolkit for building modeling frameworks (part of Rails).
|
|
138
138
|
test_files: []
|