activemodel 7.0.8.1 → 7.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
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).