activemodel 7.0.8.1 → 7.1.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.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +132 -196
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +9 -9
  5. data/lib/active_model/access.rb +16 -0
  6. data/lib/active_model/api.rb +5 -5
  7. data/lib/active_model/attribute/user_provided_default.rb +4 -0
  8. data/lib/active_model/attribute.rb +26 -1
  9. data/lib/active_model/attribute_assignment.rb +1 -1
  10. data/lib/active_model/attribute_methods.rb +102 -63
  11. data/lib/active_model/attribute_registration.rb +77 -0
  12. data/lib/active_model/attribute_set.rb +9 -0
  13. data/lib/active_model/attributes.rb +62 -45
  14. data/lib/active_model/callbacks.rb +5 -5
  15. data/lib/active_model/conversion.rb +14 -4
  16. data/lib/active_model/deprecator.rb +7 -0
  17. data/lib/active_model/dirty.rb +134 -13
  18. data/lib/active_model/error.rb +4 -3
  19. data/lib/active_model/errors.rb +17 -12
  20. data/lib/active_model/forbidden_attributes_protection.rb +2 -0
  21. data/lib/active_model/gem_version.rb +4 -4
  22. data/lib/active_model/lint.rb +1 -1
  23. data/lib/active_model/locale/en.yml +4 -3
  24. data/lib/active_model/model.rb +26 -2
  25. data/lib/active_model/naming.rb +29 -10
  26. data/lib/active_model/railtie.rb +4 -0
  27. data/lib/active_model/secure_password.rb +61 -23
  28. data/lib/active_model/serialization.rb +3 -3
  29. data/lib/active_model/serializers/json.rb +1 -1
  30. data/lib/active_model/translation.rb +18 -16
  31. data/lib/active_model/type/big_integer.rb +23 -1
  32. data/lib/active_model/type/binary.rb +7 -1
  33. data/lib/active_model/type/boolean.rb +11 -9
  34. data/lib/active_model/type/date.rb +28 -2
  35. data/lib/active_model/type/date_time.rb +45 -3
  36. data/lib/active_model/type/decimal.rb +39 -1
  37. data/lib/active_model/type/float.rb +30 -1
  38. data/lib/active_model/type/helpers/accepts_multiparameter_time.rb +5 -1
  39. data/lib/active_model/type/helpers/numeric.rb +4 -0
  40. data/lib/active_model/type/helpers/time_value.rb +28 -12
  41. data/lib/active_model/type/immutable_string.rb +37 -1
  42. data/lib/active_model/type/integer.rb +44 -1
  43. data/lib/active_model/type/serialize_cast_value.rb +47 -0
  44. data/lib/active_model/type/string.rb +9 -1
  45. data/lib/active_model/type/time.rb +48 -7
  46. data/lib/active_model/type/value.rb +17 -1
  47. data/lib/active_model/type.rb +1 -0
  48. data/lib/active_model/validations/absence.rb +1 -1
  49. data/lib/active_model/validations/acceptance.rb +1 -1
  50. data/lib/active_model/validations/callbacks.rb +4 -4
  51. data/lib/active_model/validations/clusivity.rb +5 -8
  52. data/lib/active_model/validations/comparability.rb +0 -11
  53. data/lib/active_model/validations/comparison.rb +15 -7
  54. data/lib/active_model/validations/confirmation.rb +1 -1
  55. data/lib/active_model/validations/format.rb +6 -7
  56. data/lib/active_model/validations/length.rb +10 -8
  57. data/lib/active_model/validations/numericality.rb +35 -23
  58. data/lib/active_model/validations/presence.rb +2 -2
  59. data/lib/active_model/validations/resolve_value.rb +26 -0
  60. data/lib/active_model/validations/validates.rb +4 -4
  61. data/lib/active_model/validations/with.rb +9 -2
  62. data/lib/active_model/validations.rb +45 -10
  63. data/lib/active_model/validator.rb +7 -5
  64. data/lib/active_model/version.rb +1 -1
  65. data/lib/active_model.rb +5 -1
  66. metadata +15 -10
@@ -6,7 +6,7 @@ module ActiveModel
6
6
  module Validations
7
7
  module ClassMethods
8
8
  # This method is a shortcut to all default validators and any custom
9
- # validator classes ending in 'Validator'. Note that Rails default
9
+ # validator classes ending in 'Validator'. Note that \Rails default
10
10
  # validators can be overridden inside specific classes by creating
11
11
  # custom validator classes in their place such as PresenceValidator.
12
12
  #
@@ -116,7 +116,7 @@ module ActiveModel
116
116
  key = "#{key.to_s.camelize}Validator"
117
117
 
118
118
  begin
119
- validator = key.include?("::") ? key.constantize : const_get(key)
119
+ validator = const_get(key)
120
120
  rescue NameError
121
121
  raise ArgumentError, "Unknown validator: '#{key}'"
122
122
  end
@@ -130,7 +130,7 @@ module ActiveModel
130
130
  # This method is used to define validations that cannot be corrected by end
131
131
  # users and are considered exceptional. So each validator defined with bang
132
132
  # or <tt>:strict</tt> option set to <tt>true</tt> will always raise
133
- # <tt>ActiveModel::StrictValidationFailed</tt> instead of adding error
133
+ # ActiveModel::StrictValidationFailed instead of adding error
134
134
  # when validation fails. See <tt>validates</tt> for more information about
135
135
  # the validation itself.
136
136
  #
@@ -144,7 +144,7 @@ module ActiveModel
144
144
  # person = Person.new
145
145
  # person.name = ''
146
146
  # person.valid?
147
- # # => ActiveModel::StrictValidationFailed: Name can't be blank
147
+ # # => ActiveModel::StrictValidationFailed: Name cant be blank
148
148
  def validates!(*attributes)
149
149
  options = attributes.extract_options!
150
150
  options[:strict] = true
@@ -45,6 +45,13 @@ module ActiveModel
45
45
  # validates_with MyValidator, MyOtherValidator, on: :create
46
46
  # end
47
47
  #
48
+ # There is no default error message for +validates_with+. You must
49
+ # manually add errors to the record's errors collection in the validator
50
+ # class.
51
+ #
52
+ # To implement the validate method, you must have a +record+ parameter
53
+ # defined, which is the record to be validated.
54
+ #
48
55
  # Configuration options:
49
56
  # * <tt>:on</tt> - Specifies the contexts where this validation is active.
50
57
  # Runs in all validation contexts by default +nil+. You can pass a symbol
@@ -83,7 +90,7 @@ module ActiveModel
83
90
  options[:class] = self
84
91
 
85
92
  args.each do |klass|
86
- validator = klass.new(options, &block)
93
+ validator = klass.new(options.dup, &block)
87
94
 
88
95
  if validator.respond_to?(:attributes) && !validator.attributes.empty?
89
96
  validator.attributes.each do |attribute|
@@ -139,7 +146,7 @@ module ActiveModel
139
146
  options[:class] = self.class
140
147
 
141
148
  args.each do |klass|
142
- validator = klass.new(options, &block)
149
+ validator = klass.new(options.dup, &block)
143
150
  validator.validate(self)
144
151
  end
145
152
  end
@@ -3,7 +3,7 @@
3
3
  require "active_support/core_ext/array/extract_options"
4
4
 
5
5
  module ActiveModel
6
- # == Active \Model \Validations
6
+ # = Active \Model \Validations
7
7
  #
8
8
  # Provides a full validation framework to your objects.
9
9
  #
@@ -31,7 +31,7 @@ module ActiveModel
31
31
  # person.invalid? # => true
32
32
  # person.errors.messages # => {first_name:["starts with z."]}
33
33
  #
34
- # Note that <tt>ActiveModel::Validations</tt> automatically adds an +errors+
34
+ # Note that +ActiveModel::Validations+ automatically adds an +errors+
35
35
  # method to your instances initialized with a new ActiveModel::Errors
36
36
  # object, so there is no need for you to do this manually.
37
37
  module Validations
@@ -45,6 +45,25 @@ 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
+ ##
48
67
  attr_accessor :validation_context
49
68
  private :validation_context=
50
69
  define_callbacks :validate, scope: :name
@@ -161,12 +180,7 @@ module ActiveModel
161
180
  end
162
181
 
163
182
  if options.key?(:on)
164
- options = options.dup
165
- options[:on] = Array(options[:on])
166
- options[:if] = [
167
- ->(o) { !(options[:on] & Array(o.validation_context)).empty? },
168
- *options[:if]
169
- ]
183
+ options = options.merge(if: [predicate_for_validation_context(options[:on]), *options[:if]])
170
184
  end
171
185
 
172
186
  set_callback(:validate, *args, options, &block)
@@ -277,6 +291,21 @@ module ActiveModel
277
291
  base._validators = dup.each { |k, v| dup[k] = v.dup }
278
292
  super
279
293
  end
294
+
295
+ private
296
+ @@predicates_for_validation_contexts = {}
297
+
298
+ def predicate_for_validation_context(context)
299
+ context = context.is_a?(Array) ? context.sort : Array(context)
300
+
301
+ @@predicates_for_validation_contexts[context] ||= -> (model) do
302
+ if model.validation_context.is_a?(Array)
303
+ model.validation_context.any? { |model_context| context.include?(model_context) }
304
+ else
305
+ context.include?(model.validation_context)
306
+ end
307
+ end
308
+ end
280
309
  end
281
310
 
282
311
  # Clean the +Errors+ object if instance is duped.
@@ -297,7 +326,7 @@ module ActiveModel
297
326
  #
298
327
  # person = Person.new
299
328
  # person.valid? # => false
300
- # person.errors # => #<ActiveModel::Errors:0x007fe603816640 @messages={name:["can't be blank"]}>
329
+ # person.errors # => #<ActiveModel::Errors:0x007fe603816640 @messages={name:["cant be blank"]}>
301
330
  def errors
302
331
  @errors ||= Errors.new(self)
303
332
  end
@@ -402,6 +431,12 @@ module ActiveModel
402
431
  alias :read_attribute_for_validation :send
403
432
 
404
433
  private
434
+ def init_internals
435
+ super
436
+ @errors = nil
437
+ @validation_context = nil
438
+ end
439
+
405
440
  def run_validations!
406
441
  _run_validate_callbacks
407
442
  errors.empty?
@@ -412,7 +447,7 @@ module ActiveModel
412
447
  end
413
448
  end
414
449
 
415
- # = Active Model ValidationError
450
+ # = Active \Model \ValidationError
416
451
  #
417
452
  # Raised by <tt>validate!</tt> when the model is invalid. Use the
418
453
  # +model+ method to retrieve the record which did not validate.
@@ -3,7 +3,7 @@
3
3
  require "active_support/core_ext/module/anonymous"
4
4
 
5
5
  module ActiveModel
6
- # == Active \Model \Validator
6
+ # = Active \Model \Validator
7
7
  #
8
8
  # A simple base class that can be used along with
9
9
  # ActiveModel::Validations::ClassMethods.validates_with
@@ -26,7 +26,7 @@ module ActiveModel
26
26
  # end
27
27
  # end
28
28
  #
29
- # Any class that inherits from ActiveModel::Validator must implement a method
29
+ # Any class that inherits from \ActiveModel::Validator must implement a method
30
30
  # called +validate+ which accepts a +record+.
31
31
  #
32
32
  # class Person
@@ -65,7 +65,7 @@ module ActiveModel
65
65
  # life cycle, and not on each validation run.
66
66
  #
67
67
  # The easiest way to add custom validators for validating individual attributes
68
- # is with the convenient ActiveModel::EachValidator.
68
+ # is with the convenient ActiveModel::EachValidator class.
69
69
  #
70
70
  # class TitleValidator < ActiveModel::EachValidator
71
71
  # def validate_each(record, attribute, value)
@@ -73,8 +73,8 @@ module ActiveModel
73
73
  # end
74
74
  # end
75
75
  #
76
- # This can now be used in combination with the +validates+ method
77
- # (see ActiveModel::Validations::ClassMethods#validates for more on this).
76
+ # This can now be used in combination with the +validates+ method.
77
+ # See ActiveModel::Validations::ClassMethods#validates for more on this.
78
78
  #
79
79
  # class Person
80
80
  # include ActiveModel::Validations
@@ -124,6 +124,8 @@ module ActiveModel
124
124
  end
125
125
  end
126
126
 
127
+ # = Active \Model \EachValidator
128
+ #
127
129
  # +EachValidator+ is a validator which iterates through the attributes given
128
130
  # in the options hash invoking the <tt>validate_each</tt> method passing in the
129
131
  # record, attribute, and value.
@@ -3,7 +3,7 @@
3
3
  require_relative "gem_version"
4
4
 
5
5
  module ActiveModel
6
- # Returns the currently loaded version of \Active \Model as a <tt>Gem::Version</tt>.
6
+ # Returns the currently loaded version of \Active \Model as a +Gem::Version+.
7
7
  def self.version
8
8
  gem_version
9
9
  end
data/lib/active_model.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # Copyright (c) 2004-2022 David Heinemeier Hansson
4
+ # Copyright (c) David Heinemeier Hansson
5
5
  #
6
6
  # Permission is hereby granted, free of charge, to any person obtaining
7
7
  # a copy of this software and associated documentation files (the
@@ -26,15 +26,19 @@
26
26
  require "active_support"
27
27
  require "active_support/rails"
28
28
  require "active_model/version"
29
+ require "active_model/deprecator"
29
30
 
31
+ # :include: activemodel/README.rdoc
30
32
  module ActiveModel
31
33
  extend ActiveSupport::Autoload
32
34
 
35
+ autoload :Access
33
36
  autoload :API
34
37
  autoload :Attribute
35
38
  autoload :Attributes
36
39
  autoload :AttributeAssignment
37
40
  autoload :AttributeMethods
41
+ autoload :AttributeRegistration
38
42
  autoload :BlockValidator, "active_model/validator"
39
43
  autoload :Callbacks
40
44
  autoload :Conversion
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.0.8.1
4
+ version: 7.1.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-02-21 00:00:00.000000000 Z
11
+ date: 2023-09-13 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.0.8.1
19
+ version: 7.1.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.0.8.1
26
+ version: 7.1.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.
@@ -36,18 +36,21 @@ files:
36
36
  - MIT-LICENSE
37
37
  - README.rdoc
38
38
  - lib/active_model.rb
39
+ - lib/active_model/access.rb
39
40
  - lib/active_model/api.rb
40
41
  - lib/active_model/attribute.rb
41
42
  - lib/active_model/attribute/user_provided_default.rb
42
43
  - lib/active_model/attribute_assignment.rb
43
44
  - lib/active_model/attribute_methods.rb
44
45
  - lib/active_model/attribute_mutation_tracker.rb
46
+ - lib/active_model/attribute_registration.rb
45
47
  - lib/active_model/attribute_set.rb
46
48
  - lib/active_model/attribute_set/builder.rb
47
49
  - lib/active_model/attribute_set/yaml_encoder.rb
48
50
  - lib/active_model/attributes.rb
49
51
  - lib/active_model/callbacks.rb
50
52
  - lib/active_model/conversion.rb
53
+ - lib/active_model/deprecator.rb
51
54
  - lib/active_model/dirty.rb
52
55
  - lib/active_model/error.rb
53
56
  - lib/active_model/errors.rb
@@ -80,6 +83,7 @@ files:
80
83
  - lib/active_model/type/immutable_string.rb
81
84
  - lib/active_model/type/integer.rb
82
85
  - lib/active_model/type/registry.rb
86
+ - lib/active_model/type/serialize_cast_value.rb
83
87
  - lib/active_model/type/string.rb
84
88
  - lib/active_model/type/time.rb
85
89
  - lib/active_model/type/value.rb
@@ -98,6 +102,7 @@ files:
98
102
  - lib/active_model/validations/length.rb
99
103
  - lib/active_model/validations/numericality.rb
100
104
  - lib/active_model/validations/presence.rb
105
+ - lib/active_model/validations/resolve_value.rb
101
106
  - lib/active_model/validations/validates.rb
102
107
  - lib/active_model/validations/with.rb
103
108
  - lib/active_model/validator.rb
@@ -107,10 +112,10 @@ licenses:
107
112
  - MIT
108
113
  metadata:
109
114
  bug_tracker_uri: https://github.com/rails/rails/issues
110
- changelog_uri: https://github.com/rails/rails/blob/v7.0.8.1/activemodel/CHANGELOG.md
111
- documentation_uri: https://api.rubyonrails.org/v7.0.8.1/
115
+ changelog_uri: https://github.com/rails/rails/blob/v7.1.0.beta1/activemodel/CHANGELOG.md
116
+ documentation_uri: https://api.rubyonrails.org/v7.1.0.beta1/
112
117
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
113
- source_code_uri: https://github.com/rails/rails/tree/v7.0.8.1/activemodel
118
+ source_code_uri: https://github.com/rails/rails/tree/v7.1.0.beta1/activemodel
114
119
  rubygems_mfa_required: 'true'
115
120
  post_install_message:
116
121
  rdoc_options: []
@@ -123,11 +128,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
123
128
  version: 2.7.0
124
129
  required_rubygems_version: !ruby/object:Gem::Requirement
125
130
  requirements:
126
- - - ">="
131
+ - - ">"
127
132
  - !ruby/object:Gem::Version
128
- version: '0'
133
+ version: 1.3.1
129
134
  requirements: []
130
- rubygems_version: 3.2.22
135
+ rubygems_version: 3.4.18
131
136
  signing_key:
132
137
  specification_version: 4
133
138
  summary: A toolkit for building modeling frameworks (part of Rails).