activemodel 7.2.1.2 → 8.0.0.beta1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5f15df1a8704856788191a6dd2ff7a4dcbfc97bc39f1010fc10291f00b4f8541
4
- data.tar.gz: 7bb664e8f4b317d7524a3fce9ecfa9050e26e52abb5f145be7da30a447250ffe
3
+ metadata.gz: 906d52ef894a9f6b8fc0eb97488a653bcf0c0b141747cf7a7d5e8dcedb65e929
4
+ data.tar.gz: '084df4c1c4a669a5d5c583bb3a579fdbe1be8f7f2bc4c24506797f9197250d3f'
5
5
  SHA512:
6
- metadata.gz: 14ed78c9526acc0f729488c0005926c11d30a4a25144d234d3c15e63b9021e68618646cdd4fc7e1729dfe2ec669bd6da65c602946e582d6b88799368d53eb920
7
- data.tar.gz: fcfcdf7ad2cdb6ba0dd9c72774023fddbcfa863da95d2bb77e4b98977d2943b487814e2f91253da840238addcc216f1a4f5bbcdb728a8fdc2b61d0169e656d58
6
+ metadata.gz: acdcc972d445a2d7576785d1b145d66f2a895a9e21e6b17acdc5ef78871e49aea0a49694d92efce03c030b82e69b176298ced1eb8244bdd836151dd9dfaa5068
7
+ data.tar.gz: 918efc3fb79b912bfbff1661cfec5f822d86f2c33a135389de8f8bba150196c85411db87fb17470bccfea852ff3cda3c5c19bdc336d85238040f99ee0374138d
data/CHANGELOG.md CHANGED
@@ -1,39 +1,73 @@
1
- ## Rails 7.2.1.2 (October 23, 2024) ##
1
+ ## Rails 8.0.0.beta1 (September 26, 2024) ##
2
2
 
3
- * No changes.
3
+ * Make `ActiveModel::Serialization#read_attribute_for_serialization` public
4
4
 
5
+ *Sean Doyle*
5
6
 
6
- ## Rails 7.2.1.1 (October 15, 2024) ##
7
+ * Add a default token generator for password reset tokens when using `has_secure_password`.
7
8
 
8
- * No changes.
9
+ ```ruby
10
+ class User < ApplicationRecord
11
+ has_secure_password
12
+ end
9
13
 
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
10
17
 
11
- ## Rails 7.2.1 (August 22, 2024) ##
18
+ # 16 minutes later...
19
+ User.find_by_password_reset_token(token) # returns nil
12
20
 
13
- * No changes.
21
+ # raises ActiveSupport::MessageVerifier::InvalidSignature since the token is expired
22
+ User.find_by_password_reset_token!(token)
23
+ ```
14
24
 
25
+ *DHH*
15
26
 
16
- ## Rails 7.2.0 (August 09, 2024) ##
27
+ * Add a load hook `active_model_translation` for `ActiveModel::Translation`.
17
28
 
18
- * Fix a bug where type casting of string to `Time` and `DateTime` doesn't
19
- calculate minus minute value in TZ offset correctly.
29
+ *Shouichi Kamiya*
20
30
 
21
- *Akira Matsuda*
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.
22
33
 
23
- * Port the `type_for_attribute` method to Active Model. Classes that include
24
- `ActiveModel::Attributes` will now provide this method. This method behaves
25
- the same for Active Model as it does for Active Record.
34
+ ```ruby
35
+ # ActiveModel::Translation.raise_on_missing_translations = false
36
+ Post.human_attribute_name("title")
37
+ => "Title"
26
38
 
27
- ```ruby
28
- class MyModel
29
- include ActiveModel::Attributes
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
30
44
 
31
- attribute :my_attribute, :integer
45
+ raise exception.respond_to?(:to_exception) ? exception.to_exception : exception
46
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
47
+ ```
48
+
49
+ *Shouichi Kamiya*
50
+
51
+ * Introduce `ActiveModel::AttributeAssignment#attribute_writer_missing`
52
+
53
+ Provide instances with an opportunity to gracefully handle assigning to an
54
+ unknown attribute:
55
+
56
+ ```ruby
57
+ class Rectangle
58
+ include ActiveModel::AttributeAssignment
59
+
60
+ attr_accessor :length, :width
61
+
62
+ def attribute_writer_missing(name, value)
63
+ Rails.logger.warn "Tried to assign to unknown attribute #{name}"
32
64
  end
65
+ end
33
66
 
34
- MyModel.type_for_attribute(:my_attribute) # => #<ActiveModel::Type::Integer ...>
35
- ```
67
+ rectangle = Rectangle.new
68
+ rectangle.assign_attributes(height: 10) # => Logs "Tried to assign to unknown attribute 'height'"
69
+ ```
36
70
 
37
- *Jonathan Hefner*
71
+ *Sean Doyle*
38
72
 
39
- 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
@@ -215,7 +215,12 @@ module ActiveModel
215
215
  end
216
216
 
217
217
  def generate_alias_attribute_methods(code_generator, new_name, old_name)
218
- define_attribute_method(old_name, _owner: code_generator, as: new_name)
218
+ ActiveSupport::CodeGenerator.batch(code_generator, __FILE__, __LINE__) do |owner|
219
+ attribute_method_patterns.each do |pattern|
220
+ alias_attribute_method_definition(code_generator, pattern, new_name, old_name)
221
+ end
222
+ attribute_method_patterns_cache.clear
223
+ end
219
224
  end
220
225
 
221
226
  def alias_attribute_method_definition(code_generator, pattern, new_name, old_name) # :nodoc:
@@ -228,7 +233,7 @@ module ActiveModel
228
233
  call_args = []
229
234
  call_args << parameters if parameters
230
235
 
231
- define_call(code_generator, method_name, target_name, mangled_name, parameters, call_args, namespace: :alias_attribute)
236
+ define_call(code_generator, method_name, target_name, mangled_name, parameters, call_args, namespace: :alias_attribute, as: method_name)
232
237
  end
233
238
 
234
239
  # Is +new_name+ an alias?
@@ -441,7 +446,7 @@ module ActiveModel
441
446
  mangled_name = name
442
447
 
443
448
  unless NAME_COMPILABLE_REGEXP.match?(name)
444
- mangled_name = "__temp__#{name.unpack1("h*")}"
449
+ mangled_name = :"__temp__#{name.unpack1("h*")}"
445
450
  end
446
451
 
447
452
  mangled_name
@@ -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 = 1
13
- PRE = "2"
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.1.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-23 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.1.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.1.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.1.2/activemodel/CHANGELOG.md
116
- documentation_uri: https://api.rubyonrails.org/v7.2.1.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.1.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
  - - ">="