activemodel 7.2.3 → 8.1.3

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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +36 -56
  3. data/lib/active_model/attribute/user_provided_default.rb +10 -0
  4. data/lib/active_model/attribute.rb +9 -1
  5. data/lib/active_model/attribute_assignment.rb +22 -1
  6. data/lib/active_model/attribute_methods.rb +4 -4
  7. data/lib/active_model/attribute_mutation_tracker.rb +5 -5
  8. data/lib/active_model/attribute_set.rb +1 -1
  9. data/lib/active_model/attributes/normalization.rb +197 -0
  10. data/lib/active_model/conversion.rb +1 -1
  11. data/lib/active_model/dirty.rb +11 -4
  12. data/lib/active_model/error.rb +3 -2
  13. data/lib/active_model/errors.rb +1 -4
  14. data/lib/active_model/gem_version.rb +2 -2
  15. data/lib/active_model/lint.rb +7 -3
  16. data/lib/active_model/naming.rb +0 -1
  17. data/lib/active_model/nested_error.rb +1 -3
  18. data/lib/active_model/railtie.rb +8 -4
  19. data/lib/active_model/secure_password.rb +60 -3
  20. data/lib/active_model/serialization.rb +21 -21
  21. data/lib/active_model/translation.rb +8 -3
  22. data/lib/active_model/type/big_integer.rb +21 -0
  23. data/lib/active_model/type/boolean.rb +1 -0
  24. data/lib/active_model/type/date.rb +1 -0
  25. data/lib/active_model/type/date_time.rb +8 -0
  26. data/lib/active_model/type/decimal.rb +1 -0
  27. data/lib/active_model/type/float.rb +1 -0
  28. data/lib/active_model/type/helpers/immutable.rb +13 -0
  29. data/lib/active_model/type/helpers/time_value.rb +20 -44
  30. data/lib/active_model/type/helpers.rb +1 -0
  31. data/lib/active_model/type/immutable_string.rb +2 -0
  32. data/lib/active_model/type/integer.rb +35 -19
  33. data/lib/active_model/type/string.rb +4 -0
  34. data/lib/active_model/type/value.rb +4 -4
  35. data/lib/active_model/validations/acceptance.rb +1 -1
  36. data/lib/active_model/validations/callbacks.rb +10 -0
  37. data/lib/active_model/validations/validates.rb +7 -2
  38. data/lib/active_model/validations.rb +53 -30
  39. data/lib/active_model.rb +6 -0
  40. metadata +10 -8
@@ -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] = [] }
@@ -91,6 +70,11 @@ module ActiveModel
91
70
  # or an array of symbols. (e.g. <tt>on: :create</tt> or
92
71
  # <tt>on: :custom_validation_context</tt> or
93
72
  # <tt>on: [:create, :custom_validation_context]</tt>)
73
+ # * <tt>:except_on</tt> - Specifies the contexts where this validation is not active.
74
+ # Runs in all validation contexts by default +nil+. You can pass a symbol
75
+ # or an array of symbols. (e.g. <tt>except: :create</tt> or
76
+ # <tt>except_on: :custom_validation_context</tt> or
77
+ # <tt>except_on: [:create, :custom_validation_context]</tt>)
94
78
  # * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+.
95
79
  # * <tt>:allow_blank</tt> - Skip validation if attribute is blank.
96
80
  # * <tt>:if</tt> - Specifies a method, proc, or string to call to determine
@@ -106,7 +90,7 @@ module ActiveModel
106
90
  validates_with BlockValidator, _merge_attributes(attr_names), &block
107
91
  end
108
92
 
109
- VALID_OPTIONS_FOR_VALIDATE = [:on, :if, :unless, :prepend].freeze # :nodoc:
93
+ VALID_OPTIONS_FOR_VALIDATE = [:on, :if, :unless, :prepend, :except_on].freeze # :nodoc:
110
94
 
111
95
  # Adds a validation method or block to the class. This is useful when
112
96
  # overriding the +validate+ instance method becomes too unwieldy and
@@ -158,14 +142,19 @@ module ActiveModel
158
142
  # or an array of symbols. (e.g. <tt>on: :create</tt> or
159
143
  # <tt>on: :custom_validation_context</tt> or
160
144
  # <tt>on: [:create, :custom_validation_context]</tt>)
161
- # * <tt>:if</tt> - Specifies a method, proc, or string to call to determine
145
+ # * <tt>:except_on</tt> - Specifies the contexts where this validation is not active.
146
+ # Runs in all validation contexts by default +nil+. You can pass a symbol
147
+ # or an array of symbols. (e.g. <tt>except: :create</tt> or
148
+ # <tt>except_on: :custom_validation_context</tt> or
149
+ # <tt>except_on: [:create, :custom_validation_context]</tt>)
150
+ # * <tt>:if</tt> - Specifies a method or proc to call to determine
162
151
  # if the validation should occur (e.g. <tt>if: :allow_validation</tt>,
163
- # or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method,
164
- # proc or string should return or evaluate to a +true+ or +false+ value.
165
- # * <tt>:unless</tt> - Specifies a method, proc, or string to call to
152
+ # or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method or
153
+ # proc should return or evaluate to a +true+ or +false+ value.
154
+ # * <tt>:unless</tt> - Specifies a method or proc to call to
166
155
  # determine if the validation should not occur (e.g. <tt>unless: :skip_validation</tt>,
167
156
  # or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>). The
168
- # method, proc, or string should return or evaluate to a +true+ or +false+
157
+ # method or proc should return or evaluate to a +true+ or +false+
169
158
  # value.
170
159
  #
171
160
  # NOTE: Calling +validate+ multiple times on the same method will overwrite previous definitions.
@@ -185,6 +174,15 @@ module ActiveModel
185
174
  options = options.merge(if: [predicate_for_validation_context(options[:on]), *options[:if]])
186
175
  end
187
176
 
177
+ if options.key?(:except_on)
178
+ options = options.dup
179
+ options[:except_on] = Array(options[:except_on])
180
+ options[:unless] = [
181
+ ->(o) { options[:except_on].intersect?(Array(o.validation_context)) },
182
+ *options[:unless]
183
+ ]
184
+ end
185
+
188
186
  set_callback(:validate, *args, options, &block)
189
187
  end
190
188
 
@@ -363,15 +361,23 @@ module ActiveModel
363
361
  # person.valid? # => true
364
362
  # person.valid?(:new) # => false
365
363
  def valid?(context = nil)
366
- current_context, self.validation_context = validation_context, context
364
+ current_context = validation_context
365
+ context_for_validation.context = context
367
366
  errors.clear
368
367
  run_validations!
369
368
  ensure
370
- self.validation_context = current_context
369
+ context_for_validation.context = current_context
371
370
  end
372
371
 
373
372
  alias_method :validate, :valid?
374
373
 
374
+ def freeze
375
+ errors
376
+ context_for_validation
377
+
378
+ super
379
+ end
380
+
375
381
  # Performs the opposite of <tt>valid?</tt>. Returns +true+ if errors were
376
382
  # added, +false+ otherwise.
377
383
  #
@@ -432,11 +438,24 @@ module ActiveModel
432
438
  # end
433
439
  alias :read_attribute_for_validation :send
434
440
 
441
+ # Returns the context when running validations.
442
+ def validation_context
443
+ context_for_validation.context
444
+ end
445
+
435
446
  private
447
+ def validation_context=(context)
448
+ context_for_validation.context = context
449
+ end
450
+
451
+ def context_for_validation
452
+ @context_for_validation ||= ValidationContext.new
453
+ end
454
+
436
455
  def init_internals
437
456
  super
438
457
  @errors = nil
439
- @validation_context = nil
458
+ @context_for_validation = nil
440
459
  end
441
460
 
442
461
  def run_validations!
@@ -468,6 +487,10 @@ module ActiveModel
468
487
  super(I18n.t(:"#{@model.class.i18n_scope}.errors.messages.model_invalid", errors: errors, default: :"errors.messages.model_invalid"))
469
488
  end
470
489
  end
490
+
491
+ class ValidationContext # :nodoc:
492
+ attr_accessor :context
493
+ end
471
494
  end
472
495
 
473
496
  Dir[File.expand_path("validations/*.rb", __dir__)].each { |file| require file }
data/lib/active_model.rb CHANGED
@@ -56,6 +56,12 @@ module ActiveModel
56
56
  autoload :Validations
57
57
  autoload :Validator
58
58
 
59
+ module Attributes
60
+ extend ActiveSupport::Autoload
61
+
62
+ autoload :Normalization
63
+ end
64
+
59
65
  eager_autoload do
60
66
  autoload :Errors
61
67
  autoload :Error
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: 7.2.3
4
+ version: 8.1.3
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: 7.2.3
18
+ version: 8.1.3
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: 7.2.3
25
+ version: 8.1.3
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.
@@ -47,6 +47,7 @@ files:
47
47
  - lib/active_model/attribute_set/builder.rb
48
48
  - lib/active_model/attribute_set/yaml_encoder.rb
49
49
  - lib/active_model/attributes.rb
50
+ - lib/active_model/attributes/normalization.rb
50
51
  - lib/active_model/callbacks.rb
51
52
  - lib/active_model/conversion.rb
52
53
  - lib/active_model/deprecator.rb
@@ -75,6 +76,7 @@ files:
75
76
  - lib/active_model/type/float.rb
76
77
  - lib/active_model/type/helpers.rb
77
78
  - lib/active_model/type/helpers/accepts_multiparameter_time.rb
79
+ - lib/active_model/type/helpers/immutable.rb
78
80
  - lib/active_model/type/helpers/mutable.rb
79
81
  - lib/active_model/type/helpers/numeric.rb
80
82
  - lib/active_model/type/helpers/time_value.rb
@@ -111,10 +113,10 @@ licenses:
111
113
  - MIT
112
114
  metadata:
113
115
  bug_tracker_uri: https://github.com/rails/rails/issues
114
- changelog_uri: https://github.com/rails/rails/blob/v7.2.3/activemodel/CHANGELOG.md
115
- documentation_uri: https://api.rubyonrails.org/v7.2.3/
116
+ changelog_uri: https://github.com/rails/rails/blob/v8.1.3/activemodel/CHANGELOG.md
117
+ documentation_uri: https://api.rubyonrails.org/v8.1.3/
116
118
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
117
- source_code_uri: https://github.com/rails/rails/tree/v7.2.3/activemodel
119
+ source_code_uri: https://github.com/rails/rails/tree/v8.1.3/activemodel
118
120
  rubygems_mfa_required: 'true'
119
121
  rdoc_options: []
120
122
  require_paths:
@@ -123,14 +125,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
123
125
  requirements:
124
126
  - - ">="
125
127
  - !ruby/object:Gem::Version
126
- version: 3.1.0
128
+ version: 3.2.0
127
129
  required_rubygems_version: !ruby/object:Gem::Requirement
128
130
  requirements:
129
131
  - - ">="
130
132
  - !ruby/object:Gem::Version
131
133
  version: '0'
132
134
  requirements: []
133
- rubygems_version: 3.6.9
135
+ rubygems_version: 4.0.6
134
136
  specification_version: 4
135
137
  summary: A toolkit for building modeling frameworks (part of Rails).
136
138
  test_files: []