activemodel 5.2.8.1 → 6.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +38 -168
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/lib/active_model/attribute/user_provided_default.rb +1 -2
  6. data/lib/active_model/attribute.rb +3 -4
  7. data/lib/active_model/attribute_assignment.rb +1 -1
  8. data/lib/active_model/attribute_methods.rb +39 -1
  9. data/lib/active_model/attribute_mutation_tracker.rb +1 -6
  10. data/lib/active_model/attribute_set/builder.rb +1 -3
  11. data/lib/active_model/attribute_set/yaml_encoder.rb +1 -2
  12. data/lib/active_model/attribute_set.rb +2 -10
  13. data/lib/active_model/attributes.rb +10 -22
  14. data/lib/active_model/callbacks.rb +10 -7
  15. data/lib/active_model/conversion.rb +1 -1
  16. data/lib/active_model/dirty.rb +2 -2
  17. data/lib/active_model/errors.rb +90 -11
  18. data/lib/active_model/gem_version.rb +4 -4
  19. data/lib/active_model/naming.rb +19 -3
  20. data/lib/active_model/railtie.rb +6 -0
  21. data/lib/active_model/secure_password.rb +48 -55
  22. data/lib/active_model/serializers/json.rb +10 -9
  23. data/lib/active_model/type/binary.rb +1 -1
  24. data/lib/active_model/type/boolean.rb +1 -10
  25. data/lib/active_model/type/date.rb +1 -2
  26. data/lib/active_model/type/date_time.rb +3 -4
  27. data/lib/active_model/type/decimal.rb +4 -0
  28. data/lib/active_model/type/helpers/time_value.rb +19 -1
  29. data/lib/active_model/type/helpers.rb +0 -1
  30. data/lib/active_model/type/integer.rb +1 -6
  31. data/lib/active_model/type/registry.rb +2 -10
  32. data/lib/active_model/type/string.rb +2 -2
  33. data/lib/active_model/type/time.rb +0 -5
  34. data/lib/active_model/validations/acceptance.rb +4 -8
  35. data/lib/active_model/validations/clusivity.rb +1 -1
  36. data/lib/active_model/validations/confirmation.rb +2 -2
  37. data/lib/active_model/validations/inclusion.rb +1 -1
  38. data/lib/active_model/validations/numericality.rb +9 -6
  39. data/lib/active_model/validations/validates.rb +2 -2
  40. data/lib/active_model/validations.rb +0 -2
  41. data/lib/active_model/validator.rb +1 -1
  42. data/lib/active_model.rb +1 -1
  43. metadata +13 -14
  44. data/lib/active_model/type/helpers/timezone.rb +0 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d7f6668533dd90a9b8c479fc71940522acf40284b4604e8d689d637129e6795a
4
- data.tar.gz: 9a519747c7fc021167852457a0e03056bc68351001f61d366d32386afe584d11
3
+ metadata.gz: 69b55e1af8331655f54dbced151a75b1ccbd7e48757fc4a3fd1ee2e5f2236d5a
4
+ data.tar.gz: e756ba5fc97ccd6ee212f32568e58e372b6e94d79082c81711b8e39ac6d86a3a
5
5
  SHA512:
6
- metadata.gz: 0f5a6ba7be9164544db261136c14337a256ad42cf9776e8364b745a6ff2c90f32f5e7a53e24ddb6032971de7e6bca59cf27808dea11d060ab5c3b20b92baef9d
7
- data.tar.gz: b63d763a8de2b5438801b3698f33522cd68f37c22de007d752a4d1d9250b6f2ed31aab780cc07c4179670c863bb517286b85dd77ffb9cdb1624cbf5cbbe3935b
6
+ metadata.gz: 394b1945a1c68549337a884d68985f0e15c2cbef0e0f968ee50ab55076327e6d55558d9d884d580b7359ea87f460c9a31211090f621f919b3967aa2e9b93188d
7
+ data.tar.gz: 0e1e72d58afc1f7b3f572276c9efa4b21586fa4741d8e31ab2c3bf7bb19e98888f571731d4b5dc04c0ae5f76e5e6c8ee4cf481458eef8e1669c03445277317ec
data/CHANGELOG.md CHANGED
@@ -1,118 +1,17 @@
1
- ## Rails 5.2.8.1 (July 12, 2022) ##
1
+ ## Rails 6.0.0.beta1 (January 18, 2019) ##
2
2
 
3
- * No changes.
3
+ * Add `ActiveModel::Errors#of_kind?`.
4
4
 
5
-
6
- ## Rails 5.2.8 (May 09, 2022) ##
7
-
8
- * No changes.
9
-
10
-
11
- ## Rails 5.2.7.1 (April 26, 2022) ##
12
-
13
- * No changes.
14
-
15
-
16
- ## Rails 5.2.7 (March 10, 2022) ##
17
-
18
- * No changes.
19
-
20
-
21
- ## Rails 5.2.6.3 (March 08, 2022) ##
22
-
23
- * No changes.
24
-
25
-
26
- ## Rails 5.2.6.2 (February 11, 2022) ##
27
-
28
- * No changes.
29
-
30
-
31
- ## Rails 5.2.6.1 (February 11, 2022) ##
32
-
33
- * No changes.
34
-
35
-
36
- ## Rails 5.2.6 (May 05, 2021) ##
37
-
38
- * No changes.
39
-
40
-
41
- ## Rails 5.2.5 (March 26, 2021) ##
42
-
43
- * No changes.
44
-
45
-
46
- ## Rails 5.2.4.6 (May 05, 2021) ##
47
-
48
- * No changes.
49
-
50
-
51
- ## Rails 5.2.4.5 (February 10, 2021) ##
52
-
53
- * No changes.
54
-
55
-
56
- ## Rails 5.2.4.4 (September 09, 2020) ##
57
-
58
- * No changes.
59
-
60
-
61
- ## Rails 5.2.4.3 (May 18, 2020) ##
62
-
63
- * No changes.
64
-
65
-
66
- ## Rails 5.2.4.2 (March 19, 2020) ##
67
-
68
- * No changes.
69
-
70
-
71
- ## Rails 5.2.4.1 (December 18, 2019) ##
72
-
73
- * No changes.
74
-
75
-
76
- ## Rails 5.2.4 (November 27, 2019) ##
77
-
78
- * Type cast falsy boolean symbols on boolean attribute as false.
79
-
80
- Fixes #35676.
81
-
82
- *Ryuta Kamizono*
83
-
84
-
85
- ## Rails 5.2.3 (March 27, 2019) ##
86
-
87
- * Fix date value when casting a multiparameter date hash to not convert
88
- from Gregorian date to Julian date.
89
-
90
- Before:
91
-
92
- Day.new({"day(1i)"=>"1", "day(2i)"=>"1", "day(3i)"=>"1"})
93
- => #<Day id: nil, day: "0001-01-03", created_at: nil, updated_at: nil>
94
-
95
- After:
96
-
97
- Day.new({"day(1i)"=>"1", "day(2i)"=>"1", "day(3i)"=>"1"})
98
- => #<Day id: nil, day: "0001-01-01", created_at: nil, updated_at: nil>
99
-
100
- Fixes #28521.
101
-
102
- *Sayan Chakraborty*
5
+ *bogdanvlviv*, *Rafael Mendonça França*
103
6
 
104
7
  * Fix numericality equality validation of `BigDecimal` and `Float`
105
8
  by casting to `BigDecimal` on both ends of the validation.
106
9
 
107
10
  *Gannon McGibbon*
108
11
 
12
+ * Add `#slice!` method to `ActiveModel::Errors`.
109
13
 
110
- ## Rails 5.2.2.1 (March 11, 2019) ##
111
-
112
- * No changes.
113
-
114
-
115
- ## Rails 5.2.2 (December 04, 2018) ##
14
+ *Daniel López Prat*
116
15
 
117
16
  * Fix numericality validator to still use value before type cast except Active Record.
118
17
 
@@ -120,79 +19,50 @@
120
19
 
121
20
  *Ryuta Kamizono*
122
21
 
22
+ * Fix `ActiveModel::Serializers::JSON#as_json` method for timestamps.
123
23
 
124
- ## Rails 5.2.1.1 (November 27, 2018) ##
125
-
126
- * No changes.
127
-
128
-
129
- ## Rails 5.2.1 (August 07, 2018) ##
130
-
131
- * No changes.
132
-
133
-
134
- ## Rails 5.2.0 (April 09, 2018) ##
135
-
136
- * Do not lose all multiple `:includes` with options in serialization.
137
-
138
- *Mike Mangino*
139
-
140
- * Models using the attributes API with a proc default can now be marshalled.
141
-
142
- Fixes #31216.
143
-
144
- *Sean Griffin*
145
-
146
- * Fix to working before/after validation callbacks on multiple contexts.
147
-
148
- *Yoshiyuki Hirano*
24
+ Before:
25
+ ```
26
+ contact = Contact.new(created_at: Time.utc(2006, 8, 1))
27
+ contact.as_json["created_at"] # => 2006-08-01 00:00:00 UTC
28
+ ```
149
29
 
150
- * Execute `ConfirmationValidator` validation when `_confirmation`'s value is `false`.
30
+ After:
31
+ ```
32
+ contact = Contact.new(created_at: Time.utc(2006, 8, 1))
33
+ contact.as_json["created_at"] # => "2006-08-01T00:00:00.000Z"
34
+ ```
151
35
 
152
- *bogdanvlviv*
36
+ *Bogdan Gusiev*
153
37
 
154
- * Allow passing a Proc or Symbol to length validator options.
38
+ * Allows configurable attribute name for `#has_secure_password`. This
39
+ still defaults to an attribute named 'password', causing no breaking
40
+ change. There is a new method `#authenticate_XXX` where XXX is the
41
+ configured attribute name, making the existing `#authenticate` now an
42
+ alias for this when the attribute is the default 'password'.
155
43
 
156
- *Matt Rohrer*
44
+ Example:
157
45
 
158
- * Add method `#merge!` for `ActiveModel::Errors`.
46
+ class User < ActiveRecord::Base
47
+ has_secure_password :recovery_password, validations: false
48
+ end
159
49
 
160
- *Jahfer Husain*
50
+ user = User.new()
51
+ user.recovery_password = "42password"
52
+ user.recovery_password_digest # => "$2a$04$iOfhwahFymCs5weB3BNH/uX..."
53
+ user.authenticate_recovery_password('42password') # => user
161
54
 
162
- * Fix regression in numericality validator when comparing Decimal and Float input
163
- values with more scale than the schema.
55
+ *Unathi Chonco*
164
56
 
165
- *Bradley Priest*
57
+ * Add `config.active_model.i18n_full_message` in order to control whether
58
+ the `full_message` error format can be overridden at the attribute or model
59
+ level in the locale files. This is `false` by default.
166
60
 
167
- * Fix methods `#keys`, `#values` in `ActiveModel::Errors`.
61
+ *Martin Larochelle*
168
62
 
169
- Change `#keys` to only return the keys that don't have empty messages.
63
+ * Rails 6 requires Ruby 2.5.0 or newer.
170
64
 
171
- Change `#values` to only return the not empty values.
65
+ *Jeremy Daer*, *Kasper Timm Hansen*
172
66
 
173
- Example:
174
67
 
175
- # Before
176
- person = Person.new
177
- person.errors.keys # => []
178
- person.errors.values # => []
179
- person.errors.messages # => {}
180
- person.errors[:name] # => []
181
- person.errors.messages # => {:name => []}
182
- person.errors.keys # => [:name]
183
- person.errors.values # => [[]]
184
-
185
- # After
186
- person = Person.new
187
- person.errors.keys # => []
188
- person.errors.values # => []
189
- person.errors.messages # => {}
190
- person.errors[:name] # => []
191
- person.errors.messages # => {:name => []}
192
- person.errors.keys # => []
193
- person.errors.values # => []
194
-
195
- *bogdanvlviv*
196
-
197
-
198
- Please check [5-1-stable](https://github.com/rails/rails/blob/5-1-stable/activemodel/CHANGELOG.md) for previous changes.
68
+ Please check [5-2-stable](https://github.com/rails/rails/blob/5-2-stable/activemodel/CHANGELOG.md) for previous changes.
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2004-2018 David Heinemeier Hansson
1
+ Copyright (c) 2004-2019 David Heinemeier Hansson
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.rdoc CHANGED
@@ -239,7 +239,7 @@ The latest version of Active Model can be installed with RubyGems:
239
239
 
240
240
  Source code can be downloaded as part of the Rails project on GitHub
241
241
 
242
- * https://github.com/rails/rails/tree/5-2-stable/activemodel
242
+ * https://github.com/rails/rails/tree/master/activemodel
243
243
 
244
244
 
245
245
  == License
@@ -44,8 +44,7 @@ module ActiveModel
44
44
  end
45
45
  end
46
46
 
47
- protected
48
-
47
+ private
49
48
  attr_reader :user_provided_value
50
49
  end
51
50
  end
@@ -133,10 +133,6 @@ module ActiveModel
133
133
  end
134
134
 
135
135
  protected
136
-
137
- attr_reader :original_attribute
138
- alias_method :assigned?, :original_attribute
139
-
140
136
  def original_value_for_database
141
137
  if assigned?
142
138
  original_attribute.original_value_for_database
@@ -146,6 +142,9 @@ module ActiveModel
146
142
  end
147
143
 
148
144
  private
145
+ attr_reader :original_attribute
146
+ alias :assigned? :original_attribute
147
+
149
148
  def initialize_dup(other)
150
149
  if defined?(@value) && @value.duplicable?
151
150
  @value = @value.dup
@@ -27,7 +27,7 @@ module ActiveModel
27
27
  # cat.status # => 'sleeping'
28
28
  def assign_attributes(new_attributes)
29
29
  if !new_attributes.respond_to?(:stringify_keys)
30
- raise ArgumentError, "When assigning attributes, you must pass a hash as an argument."
30
+ raise ArgumentError, "When assigning attributes, you must pass a hash as an argument, #{new_attributes.class} passed."
31
31
  end
32
32
  return if new_attributes.empty?
33
33
 
@@ -369,7 +369,7 @@ module ActiveModel
369
369
  "define_method(:'#{name}') do |*args|"
370
370
  end
371
371
 
372
- extra = (extra.map!(&:inspect) << "*args").join(", ".freeze)
372
+ extra = (extra.map!(&:inspect) << "*args").join(", ")
373
373
 
374
374
  target = if CALL_COMPILABLE_REGEXP.match?(send)
375
375
  "#{"self." unless include_private}#{send}(#{extra})"
@@ -474,5 +474,43 @@ module ActiveModel
474
474
  def _read_attribute(attr)
475
475
  __send__(attr)
476
476
  end
477
+
478
+ module AttrNames # :nodoc:
479
+ DEF_SAFE_NAME = /\A[a-zA-Z_]\w*\z/
480
+
481
+ # We want to generate the methods via module_eval rather than
482
+ # define_method, because define_method is slower on dispatch.
483
+ # Evaluating many similar methods may use more memory as the instruction
484
+ # sequences are duplicated and cached (in MRI). define_method may
485
+ # be slower on dispatch, but if you're careful about the closure
486
+ # created, then define_method will consume much less memory.
487
+ #
488
+ # But sometimes the database might return columns with
489
+ # characters that are not allowed in normal method names (like
490
+ # 'my_column(omg)'. So to work around this we first define with
491
+ # the __temp__ identifier, and then use alias method to rename
492
+ # it to what we want.
493
+ #
494
+ # We are also defining a constant to hold the frozen string of
495
+ # the attribute name. Using a constant means that we do not have
496
+ # to allocate an object on each call to the attribute method.
497
+ # Making it frozen means that it doesn't get duped when used to
498
+ # key the @attributes in read_attribute.
499
+ def self.define_attribute_accessor_method(mod, attr_name, writer: false)
500
+ method_name = "#{attr_name}#{'=' if writer}"
501
+ if attr_name.ascii_only? && DEF_SAFE_NAME.match?(attr_name)
502
+ yield method_name, "'#{attr_name}'.freeze"
503
+ else
504
+ safe_name = attr_name.unpack1("h*")
505
+ const_name = "ATTR_#{safe_name}"
506
+ const_set(const_name, attr_name) unless const_defined?(const_name)
507
+ temp_method_name = "__temp__#{safe_name}#{'=' if writer}"
508
+ attr_name_expr = "::ActiveModel::AttributeMethods::AttrNames::#{const_name}"
509
+ yield temp_method_name, attr_name_expr
510
+ mod.alias_method method_name, temp_method_name
511
+ mod.undef_method temp_method_name
512
+ end
513
+ end
514
+ end
477
515
  end
478
516
  end
@@ -69,13 +69,8 @@ module ActiveModel
69
69
  forced_changes << attr_name.to_s
70
70
  end
71
71
 
72
- # TODO Change this to private once we've dropped Ruby 2.2 support.
73
- # Workaround for Ruby 2.2 "private attribute?" warning.
74
- protected
75
-
76
- attr_reader :attributes, :forced_changes
77
-
78
72
  private
73
+ attr_reader :attributes, :forced_changes
79
74
 
80
75
  def attr_names
81
76
  attributes.keys
@@ -90,9 +90,6 @@ module ActiveModel
90
90
  end
91
91
 
92
92
  protected
93
-
94
- attr_reader :types, :values, :additional_types, :delegate_hash, :default_attributes
95
-
96
93
  def materialize
97
94
  unless @materialized
98
95
  values.each_key { |key| self[key] }
@@ -105,6 +102,7 @@ module ActiveModel
105
102
  end
106
103
 
107
104
  private
105
+ attr_reader :types, :values, :additional_types, :delegate_hash, :default_attributes
108
106
 
109
107
  def assign_default_value(name)
110
108
  type = additional_types.fetch(name, types[name])
@@ -33,8 +33,7 @@ module ActiveModel
33
33
  end
34
34
  end
35
35
 
36
- protected
37
-
36
+ private
38
37
  attr_reader :default_types
39
38
  end
40
39
  end
@@ -37,16 +37,8 @@ module ActiveModel
37
37
  attributes.each_key.select { |name| self[name].initialized? }
38
38
  end
39
39
 
40
- if defined?(JRUBY_VERSION)
41
- # This form is significantly faster on JRuby, and this is one of our biggest hotspots.
42
- # https://github.com/jruby/jruby/pull/2562
43
- def fetch_value(name, &block)
44
- self[name].value(&block)
45
- end
46
- else
47
- def fetch_value(name)
48
- self[name].value { |n| yield n if block_given? }
49
- end
40
+ def fetch_value(name, &block)
41
+ self[name].value(&block)
50
42
  end
51
43
 
52
44
  def write_from_database(name, value)
@@ -29,17 +29,16 @@ module ActiveModel
29
29
  private
30
30
 
31
31
  def define_method_attribute=(name)
32
- safe_name = name.unpack("h*".freeze).first
33
- ActiveModel::AttributeMethods::AttrNames.set_name_cache safe_name, name
34
-
35
- generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
36
- def __temp__#{safe_name}=(value)
37
- name = ::ActiveModel::AttributeMethods::AttrNames::ATTR_#{safe_name}
38
- write_attribute(name, value)
39
- end
40
- alias_method #{(name + '=').inspect}, :__temp__#{safe_name}=
41
- undef_method :__temp__#{safe_name}=
42
- STR
32
+ ActiveModel::AttributeMethods::AttrNames.define_attribute_accessor_method(
33
+ generated_attribute_methods, name, writer: true,
34
+ ) do |temp_method_name, attr_name_expr|
35
+ generated_attribute_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1
36
+ def #{temp_method_name}(value)
37
+ name = #{attr_name_expr}
38
+ write_attribute(name, value)
39
+ end
40
+ RUBY
41
+ end
43
42
  end
44
43
 
45
44
  NO_DEFAULT_PROVIDED = Object.new # :nodoc:
@@ -97,15 +96,4 @@ module ActiveModel
97
96
  write_attribute(attribute_name, value)
98
97
  end
99
98
  end
100
-
101
- module AttributeMethods #:nodoc:
102
- AttrNames = Module.new {
103
- def self.set_name_cache(name, value)
104
- const_name = "ATTR_#{name}"
105
- unless const_defined? const_name
106
- const_set const_name, value.dup.freeze
107
- end
108
- end
109
- }
110
- end
111
99
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/core_ext/array/extract_options"
4
+ require "active_support/core_ext/hash/keys"
4
5
 
5
6
  module ActiveModel
6
7
  # == Active \Model \Callbacks
@@ -127,26 +128,28 @@ module ActiveModel
127
128
  private
128
129
 
129
130
  def _define_before_model_callback(klass, callback)
130
- klass.define_singleton_method("before_#{callback}") do |*args, &block|
131
- set_callback(:"#{callback}", :before, *args, &block)
131
+ klass.define_singleton_method("before_#{callback}") do |*args, **options, &block|
132
+ options.assert_valid_keys(:if, :unless, :prepend)
133
+ set_callback(:"#{callback}", :before, *args, options, &block)
132
134
  end
133
135
  end
134
136
 
135
137
  def _define_around_model_callback(klass, callback)
136
- klass.define_singleton_method("around_#{callback}") do |*args, &block|
137
- set_callback(:"#{callback}", :around, *args, &block)
138
+ klass.define_singleton_method("around_#{callback}") do |*args, **options, &block|
139
+ options.assert_valid_keys(:if, :unless, :prepend)
140
+ set_callback(:"#{callback}", :around, *args, options, &block)
138
141
  end
139
142
  end
140
143
 
141
144
  def _define_after_model_callback(klass, callback)
142
- klass.define_singleton_method("after_#{callback}") do |*args, &block|
143
- options = args.extract_options!
145
+ klass.define_singleton_method("after_#{callback}") do |*args, **options, &block|
146
+ options.assert_valid_keys(:if, :unless, :prepend)
144
147
  options[:prepend] = true
145
148
  conditional = ActiveSupport::Callbacks::Conditionals::Value.new { |v|
146
149
  v != false
147
150
  }
148
151
  options[:if] = Array(options[:if]) << conditional
149
- set_callback(:"#{callback}", :after, *(args << options), &block)
152
+ set_callback(:"#{callback}", :after, *args, options, &block)
150
153
  end
151
154
  end
152
155
  end
@@ -103,7 +103,7 @@ module ActiveModel
103
103
  @_to_partial_path ||= begin
104
104
  element = ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(name))
105
105
  collection = ActiveSupport::Inflector.tableize(name)
106
- "#{collection}/#{element}".freeze
106
+ "#{collection}/#{element}"
107
107
  end
108
108
  end
109
109
  end
@@ -153,7 +153,7 @@ module ActiveModel
153
153
  @mutations_from_database = nil
154
154
  end
155
155
 
156
- # Returns +true+ if any of the attributes have unsaved changes, +false+ otherwise.
156
+ # Returns +true+ if any of the attributes has unsaved changes, +false+ otherwise.
157
157
  #
158
158
  # person.changed? # => false
159
159
  # person.name = 'bob'
@@ -306,7 +306,7 @@ module ActiveModel
306
306
 
307
307
  # Handles <tt>*_previous_change</tt> for +method_missing+.
308
308
  def attribute_previous_change(attr)
309
- previous_changes[attr] if attribute_previously_changed?(attr)
309
+ previous_changes[attr]
310
310
  end
311
311
 
312
312
  # Handles <tt>*_will_change!</tt> for +method_missing+.