activemodel 7.2.2 → 8.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '083ab781edd077dd1864bceb8ad069bde3954eaa020c84dddf2cd6c74490ab6a'
4
- data.tar.gz: dd7682a299773c0d0e07b43d662ec98cefca8922eeca8ba6fe80856296c32f03
3
+ metadata.gz: 906d52ef894a9f6b8fc0eb97488a653bcf0c0b141747cf7a7d5e8dcedb65e929
4
+ data.tar.gz: '084df4c1c4a669a5d5c583bb3a579fdbe1be8f7f2bc4c24506797f9197250d3f'
5
5
  SHA512:
6
- metadata.gz: cb3a9de619551c4a7685880566cbd1a8c3f230d8669980037d54611912e41772679f894625e6947ab5abeed2e974bc07cc03addbb99907ebed1927ee08d8cee2
7
- data.tar.gz: 8c723612cdf1701f67977db5f8b2634c3e5e836a1c9bb6542bfba8b459b3ccb4762db96e9854be993a947f4b946a89a4f4f2e82d493f20672ed9494db0d980c6
6
+ metadata.gz: acdcc972d445a2d7576785d1b145d66f2a895a9e21e6b17acdc5ef78871e49aea0a49694d92efce03c030b82e69b176298ced1eb8244bdd836151dd9dfaa5068
7
+ data.tar.gz: 918efc3fb79b912bfbff1661cfec5f822d86f2c33a135389de8f8bba150196c85411db87fb17470bccfea852ff3cda3c5c19bdc336d85238040f99ee0374138d
data/CHANGELOG.md CHANGED
@@ -1,61 +1,73 @@
1
- ## Rails 7.2.2 (October 30, 2024) ##
1
+ ## Rails 8.0.0.beta1 (September 26, 2024) ##
2
2
 
3
- * Fix regression in `alias_attribute` to work with user defined methods.
3
+ * Make `ActiveModel::Serialization#read_attribute_for_serialization` public
4
4
 
5
- `alias_attribute` would wrongly assume the attribute accessor was generated by Active Model.
5
+ *Sean Doyle*
6
6
 
7
- ```ruby
8
- class Person
9
- include ActiveModel::AttributeMethods
10
-
11
- define_attribute_methods :name
12
- attr_accessor :name
7
+ * Add a default token generator for password reset tokens when using `has_secure_password`.
13
8
 
14
- alias_attribute :full_name, :name
9
+ ```ruby
10
+ class User < ApplicationRecord
11
+ has_secure_password
15
12
  end
16
13
 
17
- person.full_name # => NoMethodError: undefined method `attribute' for an instance of Person
18
- ```
19
-
20
- *Jean Boussier*
21
-
22
-
23
- ## Rails 7.2.1.2 (October 23, 2024) ##
14
+ user = User.create!(name: "david", password: "123", password_confirmation: "123")
15
+ token = user.password_reset_token
16
+ User.find_by_password_reset_token(token) # returns user
24
17
 
25
- * No changes.
18
+ # 16 minutes later...
19
+ User.find_by_password_reset_token(token) # returns nil
26
20
 
21
+ # raises ActiveSupport::MessageVerifier::InvalidSignature since the token is expired
22
+ User.find_by_password_reset_token!(token)
23
+ ```
27
24
 
28
- ## Rails 7.2.1.1 (October 15, 2024) ##
29
-
30
- * No changes.
25
+ *DHH*
31
26
 
27
+ * Add a load hook `active_model_translation` for `ActiveModel::Translation`.
32
28
 
33
- ## Rails 7.2.1 (August 22, 2024) ##
29
+ *Shouichi Kamiya*
34
30
 
35
- * No changes.
31
+ * Add `raise_on_missing_translations` option to `ActiveModel::Translation`.
32
+ When the option is set, `human_attribute_name` raises an error if a translation of the given attribute is missing.
36
33
 
34
+ ```ruby
35
+ # ActiveModel::Translation.raise_on_missing_translations = false
36
+ Post.human_attribute_name("title")
37
+ => "Title"
38
+
39
+ # ActiveModel::Translation.raise_on_missing_translations = true
40
+ Post.human_attribute_name("title")
41
+ => Translation missing. Options considered were: (I18n::MissingTranslationData)
42
+ - en.activerecord.attributes.post.title
43
+ - en.attributes.title
44
+
45
+ raise exception.respond_to?(:to_exception) ? exception.to_exception : exception
46
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
47
+ ```
37
48
 
38
- ## Rails 7.2.0 (August 09, 2024) ##
49
+ *Shouichi Kamiya*
39
50
 
40
- * Fix a bug where type casting of string to `Time` and `DateTime` doesn't
41
- calculate minus minute value in TZ offset correctly.
51
+ * Introduce `ActiveModel::AttributeAssignment#attribute_writer_missing`
42
52
 
43
- *Akira Matsuda*
53
+ Provide instances with an opportunity to gracefully handle assigning to an
54
+ unknown attribute:
44
55
 
45
- * Port the `type_for_attribute` method to Active Model. Classes that include
46
- `ActiveModel::Attributes` will now provide this method. This method behaves
47
- the same for Active Model as it does for Active Record.
56
+ ```ruby
57
+ class Rectangle
58
+ include ActiveModel::AttributeAssignment
48
59
 
49
- ```ruby
50
- class MyModel
51
- include ActiveModel::Attributes
60
+ attr_accessor :length, :width
52
61
 
53
- attribute :my_attribute, :integer
62
+ def attribute_writer_missing(name, value)
63
+ Rails.logger.warn "Tried to assign to unknown attribute #{name}"
54
64
  end
65
+ end
55
66
 
56
- MyModel.type_for_attribute(:my_attribute) # => #<ActiveModel::Type::Integer ...>
57
- ```
67
+ rectangle = Rectangle.new
68
+ rectangle.assign_attributes(height: 10) # => Logs "Tried to assign to unknown attribute 'height'"
69
+ ```
58
70
 
59
- *Jonathan Hefner*
71
+ *Sean Doyle*
60
72
 
61
- Please check [7-1-stable](https://github.com/rails/rails/blob/7-1-stable/activemodel/CHANGELOG.md) for previous changes.
73
+ Please check [7-2-stable](https://github.com/rails/rails/blob/7-2-stable/activemodel/CHANGELOG.md) for previous changes.
@@ -36,6 +36,27 @@ module ActiveModel
36
36
 
37
37
  alias attributes= assign_attributes
38
38
 
39
+ # Like `BasicObject#method_missing`, `#attribute_writer_missing` is invoked
40
+ # when `#assign_attributes` is passed an unknown attribute name.
41
+ #
42
+ # By default, `#attribute_writer_missing` raises an UnknownAttributeError.
43
+ #
44
+ # class Rectangle
45
+ # include ActiveModel::AttributeAssignment
46
+ #
47
+ # attr_accessor :length, :width
48
+ #
49
+ # def attribute_writer_missing(name, value)
50
+ # Rails.logger.warn "Tried to assign to unknown attribute #{name}"
51
+ # end
52
+ # end
53
+ #
54
+ # rectangle = Rectangle.new
55
+ # rectangle.assign_attributes(height: 10) # => Logs "Tried to assign to unknown attribute 'height'"
56
+ def attribute_writer_missing(name, value)
57
+ raise UnknownAttributeError.new(self, name)
58
+ end
59
+
39
60
  private
40
61
  def _assign_attributes(attributes)
41
62
  attributes.each do |k, v|
@@ -50,7 +71,7 @@ module ActiveModel
50
71
  if respond_to?(setter)
51
72
  raise
52
73
  else
53
- raise UnknownAttributeError.new(self, k.to_s)
74
+ attribute_writer_missing(k.to_s, v)
54
75
  end
55
76
  end
56
77
  end
@@ -256,7 +256,8 @@ module ActiveModel
256
256
  end
257
257
 
258
258
  def as_json(options = {}) # :nodoc:
259
- options[:except] = [*options[:except], "mutations_from_database", "mutations_before_last_save"]
259
+ except = [*options[:except], "mutations_from_database", "mutations_before_last_save"]
260
+ options = options.merge except: except
260
261
  super(options)
261
262
  end
262
263
 
@@ -7,10 +7,10 @@ module ActiveModel
7
7
  end
8
8
 
9
9
  module VERSION
10
- MAJOR = 7
11
- MINOR = 2
12
- TINY = 2
13
- PRE = nil
10
+ MAJOR = 8
11
+ MINOR = 0
12
+ TINY = 0
13
+ PRE = "beta1"
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
@@ -39,6 +39,10 @@ module ActiveModel
39
39
  # <tt>validations: false</tt> as an argument. This allows complete
40
40
  # customizability of validation behavior.
41
41
  #
42
+ # Finally, a password reset token that's valid for 15 minutes after issue
43
+ # is automatically configured when +reset_token+ is set to true (which it is by default)
44
+ # and the object reponds to +generates_token_for+ (which Active Records do).
45
+ #
42
46
  # To use +has_secure_password+, add bcrypt (~> 3.1.7) to your Gemfile:
43
47
  #
44
48
  # gem "bcrypt", "~> 3.1.7"
@@ -98,7 +102,18 @@ module ActiveModel
98
102
  # account.is_guest = true
99
103
  # account.valid? # => true
100
104
  #
101
- def has_secure_password(attribute = :password, validations: true)
105
+ # ===== Using the password reset token
106
+ #
107
+ # user = User.create!(name: "david", password: "123", password_confirmation: "123")
108
+ # token = user.password_reset_token
109
+ # User.find_by_password_reset_token(token) # returns user
110
+ #
111
+ # # 16 minutes later...
112
+ # User.find_by_password_reset_token(token) # returns nil
113
+ #
114
+ # # raises ActiveSupport::MessageVerifier::InvalidSignature since the token is expired
115
+ # User.find_by_password_reset_token!(token)
116
+ def has_secure_password(attribute = :password, validations: true, reset_token: true)
102
117
  # Load bcrypt gem only when has_secure_password is used.
103
118
  # This is to avoid ActiveModel (and by extension the entire framework)
104
119
  # being dependent on a binary library.
@@ -109,7 +124,7 @@ module ActiveModel
109
124
  raise
110
125
  end
111
126
 
112
- include InstanceMethodsOnActivation.new(attribute)
127
+ include InstanceMethodsOnActivation.new(attribute, reset_token: reset_token)
113
128
 
114
129
  if validations
115
130
  include ActiveModel::Validations
@@ -142,11 +157,30 @@ module ActiveModel
142
157
 
143
158
  validates_confirmation_of attribute, allow_blank: true
144
159
  end
160
+
161
+ # Only generate tokens for records that are capable of doing so (Active Records, not vanilla Active Models)
162
+ if reset_token && respond_to?(:generates_token_for)
163
+ generates_token_for :"#{attribute}_reset", expires_in: 15.minutes do
164
+ public_send(:"#{attribute}_salt")&.last(10)
165
+ end
166
+
167
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
168
+ silence_redefinition_of_method :find_by_#{attribute}_reset_token
169
+ def self.find_by_#{attribute}_reset_token(token)
170
+ find_by_token_for(:#{attribute}_reset, token)
171
+ end
172
+
173
+ silence_redefinition_of_method :find_by_#{attribute}_reset_token!
174
+ def self.find_by_#{attribute}_reset_token!(token)
175
+ find_by_token_for!(:#{attribute}_reset, token)
176
+ end
177
+ RUBY
178
+ end
145
179
  end
146
180
  end
147
181
 
148
182
  class InstanceMethodsOnActivation < Module
149
- def initialize(attribute)
183
+ def initialize(attribute, reset_token:)
150
184
  attr_reader attribute
151
185
 
152
186
  define_method("#{attribute}=") do |unencrypted_password|
@@ -184,6 +218,13 @@ module ActiveModel
184
218
  end
185
219
 
186
220
  alias_method :authenticate, :authenticate_password if attribute == :password
221
+
222
+ if reset_token
223
+ # Returns the class-level configured reset token for the password.
224
+ define_method("#{attribute}_reset_token") do
225
+ generate_token_for(:"#{attribute}_reset")
226
+ end
227
+ end
187
228
  end
188
229
  end
189
230
  end
@@ -29,8 +29,8 @@ module ActiveModel
29
29
  # An +attributes+ hash must be defined and should contain any attributes you
30
30
  # need to be serialized. Attributes must be strings, not symbols.
31
31
  # When called, serializable hash will use instance methods that match the name
32
- # of the attributes hash's keys. In order to override this behavior, take a look
33
- # at the private method +read_attribute_for_serialization+.
32
+ # of the attributes hash's keys. In order to override this behavior, override
33
+ # the +read_attribute_for_serialization+ method.
34
34
  #
35
35
  # ActiveModel::Serializers::JSON module automatically includes
36
36
  # the +ActiveModel::Serialization+ module, so there is no need to
@@ -128,7 +128,7 @@ module ActiveModel
128
128
  return serializable_attributes(attribute_names) if options.blank?
129
129
 
130
130
  if only = options[:only]
131
- attribute_names &= Array(only).map(&:to_s)
131
+ attribute_names = Array(only).map(&:to_s) & attribute_names
132
132
  elsif except = options[:except]
133
133
  attribute_names -= Array(except).map(&:to_s)
134
134
  end
@@ -148,29 +148,29 @@ module ActiveModel
148
148
  hash
149
149
  end
150
150
 
151
+ # Hook method defining how an attribute value should be retrieved for
152
+ # serialization. By default this is assumed to be an instance named after
153
+ # the attribute. Override this method in subclasses should you need to
154
+ # retrieve the value for a given attribute differently:
155
+ #
156
+ # class MyClass
157
+ # include ActiveModel::Serialization
158
+ #
159
+ # def initialize(data = {})
160
+ # @data = data
161
+ # end
162
+ #
163
+ # def read_attribute_for_serialization(key)
164
+ # @data[key]
165
+ # end
166
+ # end
167
+ alias :read_attribute_for_serialization :send
168
+
151
169
  private
152
170
  def attribute_names_for_serialization
153
171
  attributes.keys
154
172
  end
155
173
 
156
- # Hook method defining how an attribute value should be retrieved for
157
- # serialization. By default this is assumed to be an instance named after
158
- # the attribute. Override this method in subclasses should you need to
159
- # retrieve the value for a given attribute differently:
160
- #
161
- # class MyClass
162
- # include ActiveModel::Serialization
163
- #
164
- # def initialize(data = {})
165
- # @data = data
166
- # end
167
- #
168
- # def read_attribute_for_serialization(key)
169
- # @data[key]
170
- # end
171
- # end
172
- alias :read_attribute_for_serialization :send
173
-
174
174
  def serializable_attributes(attribute_names)
175
175
  attribute_names.index_with { |n| read_attribute_for_serialization(n) }
176
176
  end
@@ -22,6 +22,8 @@ module ActiveModel
22
22
  module Translation
23
23
  include ActiveModel::Naming
24
24
 
25
+ singleton_class.attr_accessor :raise_on_missing_translations
26
+
25
27
  # Returns the +i18n_scope+ for the class. Override if you want custom lookup.
26
28
  def i18n_scope
27
29
  :activemodel
@@ -60,13 +62,17 @@ module ActiveModel
60
62
  end
61
63
  end
62
64
 
65
+ raise_on_missing = options.fetch(:raise, Translation.raise_on_missing_translations)
66
+
63
67
  defaults << :"attributes.#{attribute}"
64
68
  defaults << options[:default] if options[:default]
65
- defaults << MISSING_TRANSLATION
69
+ defaults << MISSING_TRANSLATION unless raise_on_missing
66
70
 
67
- translation = I18n.translate(defaults.shift, count: 1, **options, default: defaults)
71
+ translation = I18n.translate(defaults.shift, count: 1, raise: raise_on_missing, **options, default: defaults)
68
72
  translation = attribute.humanize if translation == MISSING_TRANSLATION
69
73
  translation
70
74
  end
71
75
  end
76
+
77
+ ActiveSupport.run_load_hooks(:active_model_translation, Translation)
72
78
  end
@@ -69,56 +69,32 @@ module ActiveModel
69
69
  \z
70
70
  /x
71
71
 
72
- if RUBY_VERSION >= "3.2"
73
- if Time.new(2000, 1, 1, 0, 0, 0, "-00:00").yday != 1 # Early 3.2.x had a bug
74
- # BUG: Wrapping the Time object with Time.at because Time.new with `in:` in Ruby 3.2.0
75
- # used to return an invalid Time object
76
- # see: https://bugs.ruby-lang.org/issues/19292
77
- def fast_string_to_time(string)
78
- return unless string.include?("-") # Time.new("1234") # => 1234-01-01 00:00:00
79
-
80
- if is_utc?
81
- ::Time.at(::Time.new(string, in: "UTC"))
82
- else
83
- ::Time.new(string)
84
- end
85
- rescue ArgumentError
86
- nil
87
- end
88
- else
89
- def fast_string_to_time(string)
90
- return unless string.include?("-") # Time.new("1234") # => 1234-01-01 00:00:00
91
-
92
- if is_utc?
93
- ::Time.new(string, in: "UTC")
94
- else
95
- ::Time.new(string)
96
- end
97
- rescue ArgumentError
98
- nil
72
+ if Time.new(2000, 1, 1, 0, 0, 0, "-00:00").yday != 1 # Early 3.2.x had a bug
73
+ # BUG: Wrapping the Time object with Time.at because Time.new with `in:` in Ruby 3.2.0
74
+ # used to return an invalid Time object
75
+ # see: https://bugs.ruby-lang.org/issues/19292
76
+ def fast_string_to_time(string)
77
+ return unless string.include?("-") # Time.new("1234") # => 1234-01-01 00:00:00
78
+
79
+ if is_utc?
80
+ ::Time.at(::Time.new(string, in: "UTC"))
81
+ else
82
+ ::Time.new(string)
99
83
  end
84
+ rescue ArgumentError
85
+ nil
100
86
  end
101
87
  else
102
88
  def fast_string_to_time(string)
103
- return unless ISO_DATETIME =~ string
89
+ return unless string.include?("-") # Time.new("1234") # => 1234-01-01 00:00:00
104
90
 
105
- usec = $7.to_i
106
- usec_len = $7&.length
107
- if usec_len&.< 6
108
- usec *= 10**(6 - usec_len)
91
+ if is_utc?
92
+ ::Time.new(string, in: "UTC")
93
+ else
94
+ ::Time.new(string)
109
95
  end
110
-
111
- if $8
112
- offset = \
113
- if $8 == "Z"
114
- 0
115
- else
116
- offset_h, offset_m = $8.to_i, $9.to_i
117
- offset_h.to_i * 3600 + (offset_h.negative? ? -1 : 1) * offset_m * 60
118
- end
119
- end
120
-
121
- new_time($1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, usec, offset)
96
+ rescue ArgumentError
97
+ nil
122
98
  end
123
99
  end
124
100
  end
@@ -45,27 +45,6 @@ module ActiveModel
45
45
  extend HelperMethods
46
46
  include HelperMethods
47
47
 
48
- ##
49
- # :method: validation_context
50
- # Returns the context when running validations.
51
- #
52
- # This is useful when running validations except a certain context (opposite to the +on+ option).
53
- #
54
- # class Person
55
- # include ActiveModel::Validations
56
- #
57
- # attr_accessor :name
58
- # validates :name, presence: true, if: -> { validation_context != :custom }
59
- # end
60
- #
61
- # person = Person.new
62
- # person.valid? #=> false
63
- # person.valid?(:new) #=> false
64
- # person.valid?(:custom) #=> true
65
-
66
- ##
67
- attr_accessor :validation_context
68
- private :validation_context=
69
48
  define_callbacks :validate, scope: :name
70
49
 
71
50
  class_attribute :_validators, instance_writer: false, default: Hash.new { |h, k| h[k] = [] }
@@ -361,15 +340,23 @@ module ActiveModel
361
340
  # person.valid? # => true
362
341
  # person.valid?(:new) # => false
363
342
  def valid?(context = nil)
364
- current_context, self.validation_context = validation_context, context
343
+ current_context = validation_context
344
+ context_for_validation.context = context
365
345
  errors.clear
366
346
  run_validations!
367
347
  ensure
368
- self.validation_context = current_context
348
+ context_for_validation.context = current_context
369
349
  end
370
350
 
371
351
  alias_method :validate, :valid?
372
352
 
353
+ def freeze
354
+ errors
355
+ context_for_validation
356
+
357
+ super
358
+ end
359
+
373
360
  # Performs the opposite of <tt>valid?</tt>. Returns +true+ if errors were
374
361
  # added, +false+ otherwise.
375
362
  #
@@ -430,11 +417,38 @@ module ActiveModel
430
417
  # end
431
418
  alias :read_attribute_for_validation :send
432
419
 
420
+ # Returns the context when running validations.
421
+ #
422
+ # This is useful when running validations except a certain context (opposite to the +on+ option).
423
+ #
424
+ # class Person
425
+ # include ActiveModel::Validations
426
+ #
427
+ # attr_accessor :name
428
+ # validates :name, presence: true, if: -> { validation_context != :custom }
429
+ # end
430
+ #
431
+ # person = Person.new
432
+ # person.valid? #=> false
433
+ # person.valid?(:new) #=> false
434
+ # person.valid?(:custom) #=> true
435
+ def validation_context
436
+ context_for_validation.context
437
+ end
438
+
433
439
  private
440
+ def validation_context=(context)
441
+ context_for_validation.context = context
442
+ end
443
+
444
+ def context_for_validation
445
+ @context_for_validation ||= ValidationContext.new
446
+ end
447
+
434
448
  def init_internals
435
449
  super
436
450
  @errors = nil
437
- @validation_context = nil
451
+ @context_for_validation = nil
438
452
  end
439
453
 
440
454
  def run_validations!
@@ -466,6 +480,10 @@ module ActiveModel
466
480
  super(I18n.t(:"#{@model.class.i18n_scope}.errors.messages.model_invalid", errors: errors, default: :"errors.messages.model_invalid"))
467
481
  end
468
482
  end
483
+
484
+ class ValidationContext # :nodoc:
485
+ attr_accessor :context
486
+ end
469
487
  end
470
488
 
471
489
  Dir[File.expand_path("validations/*.rb", __dir__)].each { |file| require file }
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.2.2
4
+ version: 8.0.0.beta1
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: 2024-10-31 00:00:00.000000000 Z
11
+ date: 2024-09-26 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.2.2
19
+ version: 8.0.0.beta1
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.2.2
26
+ version: 8.0.0.beta1
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,10 +112,10 @@ 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.2.2/activemodel/CHANGELOG.md
116
- documentation_uri: https://api.rubyonrails.org/v7.2.2/
115
+ changelog_uri: https://github.com/rails/rails/blob/v8.0.0.beta1/activemodel/CHANGELOG.md
116
+ documentation_uri: https://api.rubyonrails.org/v8.0.0.beta1/
117
117
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
118
- source_code_uri: https://github.com/rails/rails/tree/v7.2.2/activemodel
118
+ source_code_uri: https://github.com/rails/rails/tree/v8.0.0.beta1/activemodel
119
119
  rubygems_mfa_required: 'true'
120
120
  post_install_message:
121
121
  rdoc_options: []
@@ -125,7 +125,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
125
125
  requirements:
126
126
  - - ">="
127
127
  - !ruby/object:Gem::Version
128
- version: 3.1.0
128
+ version: 3.2.0
129
129
  required_rubygems_version: !ruby/object:Gem::Requirement
130
130
  requirements:
131
131
  - - ">="