activemodel 4.2.11.3 → 5.0.7.2
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 +4 -4
- data/CHANGELOG.md +149 -56
- data/MIT-LICENSE +1 -1
- data/README.rdoc +8 -16
- data/lib/active_model/attribute_assignment.rb +52 -0
- data/lib/active_model/attribute_methods.rb +16 -16
- data/lib/active_model/callbacks.rb +3 -3
- data/lib/active_model/conversion.rb +5 -5
- data/lib/active_model/dirty.rb +41 -40
- data/lib/active_model/errors.rb +175 -68
- data/lib/active_model/forbidden_attributes_protection.rb +3 -2
- data/lib/active_model/gem_version.rb +5 -5
- data/lib/active_model/lint.rb +32 -28
- data/lib/active_model/locale/en.yml +2 -1
- data/lib/active_model/model.rb +3 -4
- data/lib/active_model/naming.rb +5 -4
- data/lib/active_model/secure_password.rb +2 -9
- data/lib/active_model/serialization.rb +36 -9
- data/lib/active_model/type/big_integer.rb +13 -0
- data/lib/active_model/type/binary.rb +50 -0
- data/lib/active_model/type/boolean.rb +21 -0
- data/lib/active_model/type/date.rb +54 -0
- data/lib/active_model/type/date_time.rb +44 -0
- data/lib/active_model/type/decimal.rb +66 -0
- data/lib/active_model/type/decimal_without_scale.rb +11 -0
- data/lib/active_model/type/float.rb +25 -0
- data/lib/active_model/type/helpers/accepts_multiparameter_time.rb +35 -0
- data/lib/active_model/type/helpers/mutable.rb +18 -0
- data/lib/active_model/type/helpers/numeric.rb +34 -0
- data/lib/active_model/type/helpers/time_value.rb +77 -0
- data/lib/active_model/type/helpers.rb +4 -0
- data/lib/active_model/type/immutable_string.rb +29 -0
- data/lib/active_model/type/integer.rb +66 -0
- data/lib/active_model/type/registry.rb +64 -0
- data/lib/active_model/type/string.rb +24 -0
- data/lib/active_model/type/text.rb +11 -0
- data/lib/active_model/type/time.rb +42 -0
- data/lib/active_model/type/unsigned_integer.rb +15 -0
- data/lib/active_model/type/value.rb +116 -0
- data/lib/active_model/type.rb +59 -0
- data/lib/active_model/validations/absence.rb +1 -1
- data/lib/active_model/validations/acceptance.rb +57 -9
- data/lib/active_model/validations/callbacks.rb +3 -3
- data/lib/active_model/validations/clusivity.rb +4 -3
- data/lib/active_model/validations/confirmation.rb +16 -4
- data/lib/active_model/validations/exclusion.rb +3 -1
- data/lib/active_model/validations/format.rb +1 -1
- data/lib/active_model/validations/helper_methods.rb +13 -0
- data/lib/active_model/validations/inclusion.rb +3 -3
- data/lib/active_model/validations/length.rb +49 -18
- data/lib/active_model/validations/numericality.rb +20 -11
- data/lib/active_model/validations/validates.rb +1 -1
- data/lib/active_model/validations/with.rb +0 -10
- data/lib/active_model/validations.rb +34 -1
- data/lib/active_model/validator.rb +5 -5
- data/lib/active_model/version.rb +1 -1
- data/lib/active_model.rb +4 -2
- metadata +31 -22
- data/lib/active_model/serializers/xml.rb +0 -238
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 037004e060b00ef9bdf166f1a123941008eac38445bf7b69de9e4325d27ad729
|
4
|
+
data.tar.gz: 323b17aae456ed4bd2e606dc308edee6cb3abc945d806fb753248e5bc4fe2f7d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad0dec431b9629aa031fbe36c6ae295f51a2d773fa9e325833189d177201c81c678aee6eb1298607a894a415dd0d1bd0f83e91f6edc7785b7b390af6c9e43b89
|
7
|
+
data.tar.gz: 7f5c74e105297822c1d10e088a6aa16641f5cefa6d3d71fde2a2d0e0495bf10565403cb8cd66c00cd241477bb80c997ba1d5a5be3b98ef3dbd8f3d4e142d6186
|
data/CHANGELOG.md
CHANGED
@@ -1,143 +1,236 @@
|
|
1
|
-
## Rails
|
1
|
+
## Rails 5.0.7.2 (March 11, 2019) ##
|
2
2
|
|
3
3
|
* No changes.
|
4
4
|
|
5
5
|
|
6
|
-
## Rails
|
6
|
+
## Rails 5.0.7.1 (November 27, 2018) ##
|
7
7
|
|
8
8
|
* No changes.
|
9
9
|
|
10
10
|
|
11
|
-
## Rails
|
11
|
+
## Rails 5.0.7 (March 29, 2018) ##
|
12
12
|
|
13
13
|
* No changes.
|
14
14
|
|
15
15
|
|
16
|
-
## Rails
|
16
|
+
## Rails 5.0.6 (September 07, 2017) ##
|
17
17
|
|
18
18
|
* No changes.
|
19
19
|
|
20
20
|
|
21
|
-
## Rails
|
21
|
+
## Rails 5.0.6.rc1 (August 24, 2017) ##
|
22
22
|
|
23
23
|
* No changes.
|
24
24
|
|
25
25
|
|
26
|
-
## Rails
|
26
|
+
## Rails 5.0.5 (July 31, 2017) ##
|
27
27
|
|
28
28
|
* No changes.
|
29
29
|
|
30
30
|
|
31
|
-
## Rails
|
31
|
+
## Rails 5.0.5.rc2 (July 25, 2017) ##
|
32
32
|
|
33
33
|
* No changes.
|
34
34
|
|
35
35
|
|
36
|
-
## Rails
|
36
|
+
## Rails 5.0.5.rc1 (July 19, 2017) ##
|
37
37
|
|
38
38
|
* No changes.
|
39
39
|
|
40
40
|
|
41
|
-
## Rails
|
41
|
+
## Rails 5.0.4 (June 19, 2017) ##
|
42
42
|
|
43
|
-
*
|
43
|
+
* Fix regression in numericality validator when comparing Decimal and Float input
|
44
|
+
values with more scale than the schema.
|
45
|
+
|
46
|
+
*Bradley Priest*
|
47
|
+
|
48
|
+
|
49
|
+
## Rails 5.0.3 (May 12, 2017) ##
|
50
|
+
|
51
|
+
* The original string assigned to a model attribute is no longer incorrectly
|
52
|
+
frozen.
|
53
|
+
|
54
|
+
Fixes #24185, #28718.
|
55
|
+
|
56
|
+
*Matthew Draper*
|
57
|
+
|
58
|
+
* Avoid converting integer as a string into float.
|
44
59
|
|
60
|
+
*namusyaka*
|
45
61
|
|
46
|
-
|
62
|
+
|
63
|
+
## Rails 5.0.2 (March 01, 2017) ##
|
47
64
|
|
48
65
|
* No changes.
|
49
66
|
|
50
67
|
|
51
|
-
## Rails
|
68
|
+
## Rails 5.0.1 (December 21, 2016) ##
|
52
69
|
|
53
70
|
* No changes.
|
54
71
|
|
55
72
|
|
56
|
-
## Rails
|
73
|
+
## Rails 5.0.1.rc2 (December 10, 2016) ##
|
57
74
|
|
58
75
|
* No changes.
|
59
76
|
|
60
77
|
|
61
|
-
## Rails
|
78
|
+
## Rails 5.0.1.rc1 (December 01, 2016) ##
|
62
79
|
|
63
|
-
*
|
80
|
+
* Fix `Type::Date#serialize` to cast a value to a date object properly.
|
81
|
+
This casting fixes queries for finding records by date column.
|
64
82
|
|
83
|
+
Fixes #25354.
|
65
84
|
|
66
|
-
|
85
|
+
*Ryuta Kamizono*
|
67
86
|
|
68
|
-
* No Changes *
|
69
87
|
|
88
|
+
## Rails 5.0.0 (June 30, 2016) ##
|
70
89
|
|
71
|
-
|
90
|
+
* `Dirty`'s `*_changed?` methods now return an actual singleton, never `nil`, as in 4.2.
|
91
|
+
Fixes #24220.
|
72
92
|
|
73
|
-
*
|
93
|
+
*Sen-Zhang*
|
74
94
|
|
95
|
+
* Ensure that instances of `ActiveModel::Errors` can be marshalled.
|
96
|
+
Fixes #25165.
|
75
97
|
|
76
|
-
|
98
|
+
*Sean Griffin*
|
77
99
|
|
78
|
-
*
|
100
|
+
* Allow passing record being validated to the message proc to generate
|
101
|
+
customized error messages for that object using I18n helper.
|
79
102
|
|
103
|
+
*Prathamesh Sonpatki*
|
80
104
|
|
81
|
-
|
105
|
+
* Validate multiple contexts on `valid?` and `invalid?` at once.
|
82
106
|
|
83
|
-
|
107
|
+
Example:
|
84
108
|
|
85
|
-
|
109
|
+
class Person
|
110
|
+
include ActiveModel::Validations
|
86
111
|
|
87
|
-
|
112
|
+
attr_reader :name, :title
|
113
|
+
validates_presence_of :name, on: :create
|
114
|
+
validates_presence_of :title, on: :update
|
115
|
+
end
|
88
116
|
|
89
|
-
|
117
|
+
person = Person.new
|
118
|
+
person.valid?([:create, :update]) # => false
|
119
|
+
person.errors.messages # => {:name=>["can't be blank"], :title=>["can't be blank"]}
|
90
120
|
|
91
|
-
|
121
|
+
*Dmitry Polushkin*
|
92
122
|
|
93
|
-
|
123
|
+
* Add case_sensitive option for confirmation validator in models.
|
94
124
|
|
95
|
-
*
|
125
|
+
*Akshat Sharma*
|
96
126
|
|
97
|
-
|
98
|
-
|
127
|
+
* Ensure `method_missing` is called for methods passed to
|
128
|
+
`ActiveModel::Serialization#serializable_hash` that don't exist.
|
99
129
|
|
100
|
-
*
|
130
|
+
*Jay Elaraj*
|
101
131
|
|
102
|
-
*
|
132
|
+
* Remove `ActiveModel::Serializers::Xml` from core.
|
103
133
|
|
104
|
-
|
105
|
-
While `reset_name` sets the value of the name attribute to previous value
|
106
|
-
`reset_changes` only discards the changes.
|
134
|
+
*Zachary Scott*
|
107
135
|
|
108
|
-
|
136
|
+
* Add `ActiveModel::Dirty#[attr_name]_previously_changed?` and
|
137
|
+
`ActiveModel::Dirty#[attr_name]_previous_change` to improve access
|
138
|
+
to recorded changes after the model has been saved.
|
139
|
+
|
140
|
+
It makes the dirty-attributes query methods consistent before and after
|
141
|
+
saving.
|
142
|
+
|
143
|
+
*Fernando Tapia Rico*
|
144
|
+
|
145
|
+
* Deprecate the `:tokenizer` option for `validates_length_of`, in favor of
|
146
|
+
plain Ruby.
|
147
|
+
|
148
|
+
*Sean Griffin*
|
109
149
|
|
110
|
-
*
|
111
|
-
|
150
|
+
* Deprecate `ActiveModel::Errors#add_on_empty` and `ActiveModel::Errors#add_on_blank`
|
151
|
+
with no replacement.
|
112
152
|
|
113
|
-
*
|
153
|
+
*Wojciech Wnętrzak*
|
114
154
|
|
115
|
-
*
|
155
|
+
* Deprecate `ActiveModel::Errors#get`, `ActiveModel::Errors#set` and
|
156
|
+
`ActiveModel::Errors#[]=` methods that have inconsistent behavior.
|
116
157
|
|
117
|
-
*
|
158
|
+
*Wojciech Wnętrzak*
|
118
159
|
|
119
|
-
*
|
120
|
-
characters if validations are enabled.
|
160
|
+
* Allow symbol as values for `tokenize` of `LengthValidator`.
|
121
161
|
|
122
|
-
|
162
|
+
*Kensuke Naito*
|
123
163
|
|
124
|
-
|
164
|
+
* Assigning an unknown attribute key to an `ActiveModel` instance during initialization
|
165
|
+
will now raise `ActiveModel::AttributeAssignment::UnknownAttributeError` instead of
|
166
|
+
`NoMethodError`.
|
125
167
|
|
126
|
-
|
168
|
+
Example:
|
127
169
|
|
128
|
-
|
170
|
+
User.new(foo: 'some value')
|
171
|
+
# => ActiveModel::AttributeAssignment::UnknownAttributeError: unknown attribute 'foo' for User.
|
129
172
|
|
130
|
-
*
|
173
|
+
*Eugene Gilburg*
|
131
174
|
|
132
|
-
*
|
175
|
+
* Extracted `ActiveRecord::AttributeAssignment` to `ActiveModel::AttributeAssignment`
|
176
|
+
allowing to use it for any object as an includable module.
|
133
177
|
|
134
|
-
|
178
|
+
Example:
|
179
|
+
|
180
|
+
class Cat
|
181
|
+
include ActiveModel::AttributeAssignment
|
182
|
+
attr_accessor :name, :status
|
183
|
+
end
|
184
|
+
|
185
|
+
cat = Cat.new
|
186
|
+
cat.assign_attributes(name: "Gorby", status: "yawning")
|
187
|
+
cat.name # => 'Gorby'
|
188
|
+
cat.status # => 'yawning'
|
189
|
+
cat.assign_attributes(status: "sleeping")
|
190
|
+
cat.name # => 'Gorby'
|
191
|
+
cat.status # => 'sleeping'
|
192
|
+
|
193
|
+
*Bogdan Gusiev*
|
194
|
+
|
195
|
+
* Add `ActiveModel::Errors#details`
|
196
|
+
|
197
|
+
To be able to return type of used validator, one can now call `details`
|
198
|
+
on errors instance.
|
199
|
+
|
200
|
+
Example:
|
201
|
+
|
202
|
+
class User < ActiveRecord::Base
|
203
|
+
validates :name, presence: true
|
204
|
+
end
|
205
|
+
|
206
|
+
user = User.new; user.valid?; user.errors.details
|
207
|
+
=> {name: [{error: :blank}]}
|
208
|
+
|
209
|
+
*Wojciech Wnętrzak*
|
210
|
+
|
211
|
+
* Change `validates_acceptance_of` to accept `true` by default besides `'1'`.
|
212
|
+
|
213
|
+
The default for `validates_acceptance_of` is now `'1'` and `true`.
|
214
|
+
In the past, only `"1"` was the default and you were required to pass
|
215
|
+
`accept: true` separately.
|
216
|
+
|
217
|
+
*mokhan*
|
218
|
+
|
219
|
+
* Remove deprecated `ActiveModel::Dirty#reset_#{attribute}` and
|
220
|
+
`ActiveModel::Dirty#reset_changes`.
|
221
|
+
|
222
|
+
*Rafael Mendonça França*
|
135
223
|
|
136
|
-
*
|
224
|
+
* Change the way in which callback chains can be halted.
|
137
225
|
|
138
|
-
|
139
|
-
|
226
|
+
The preferred method to halt a callback chain from now on is to explicitly
|
227
|
+
`throw(:abort)`.
|
228
|
+
In the past, returning `false` in an Active Model `before_` callback had
|
229
|
+
the side effect of halting the callback chain.
|
230
|
+
This is not recommended anymore and, depending on the value of the
|
231
|
+
`ActiveSupport.halt_callback_chains_on_return_false` option, will
|
232
|
+
either not work at all or display a deprecation warning.
|
140
233
|
|
141
|
-
*
|
234
|
+
*claudiob*
|
142
235
|
|
143
|
-
Please check [4-
|
236
|
+
Please check [4-2-stable](https://github.com/rails/rails/blob/4-2-stable/activemodel/CHANGELOG.md) for previous changes.
|
data/MIT-LICENSE
CHANGED
data/README.rdoc
CHANGED
@@ -49,7 +49,7 @@ behavior out of the box:
|
|
49
49
|
send("#{attr}=", nil)
|
50
50
|
end
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
person = Person.new
|
54
54
|
person.clear_name
|
55
55
|
person.clear_age
|
@@ -132,7 +132,7 @@ behavior out of the box:
|
|
132
132
|
"Name"
|
133
133
|
end
|
134
134
|
end
|
135
|
-
|
135
|
+
|
136
136
|
person = Person.new
|
137
137
|
person.name = nil
|
138
138
|
person.validate!
|
@@ -154,8 +154,8 @@ behavior out of the box:
|
|
154
154
|
|
155
155
|
* Making objects serializable
|
156
156
|
|
157
|
-
ActiveModel::Serialization provides a standard interface for your object
|
158
|
-
to provide +to_json+
|
157
|
+
<tt>ActiveModel::Serialization</tt> provides a standard interface for your object
|
158
|
+
to provide +to_json+ serialization.
|
159
159
|
|
160
160
|
class SerialPerson
|
161
161
|
include ActiveModel::Serialization
|
@@ -177,13 +177,6 @@ behavior out of the box:
|
|
177
177
|
s = SerialPerson.new
|
178
178
|
s.to_json # => "{\"name\":null}"
|
179
179
|
|
180
|
-
class SerialPerson
|
181
|
-
include ActiveModel::Serializers::Xml
|
182
|
-
end
|
183
|
-
|
184
|
-
s = SerialPerson.new
|
185
|
-
s.to_xml # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<serial-person...
|
186
|
-
|
187
180
|
{Learn more}[link:classes/ActiveModel/Serialization.html]
|
188
181
|
|
189
182
|
* Internationalization (i18n) support
|
@@ -216,10 +209,10 @@ behavior out of the box:
|
|
216
209
|
{Learn more}[link:classes/ActiveModel/Validations.html]
|
217
210
|
|
218
211
|
* Custom validators
|
219
|
-
|
212
|
+
|
220
213
|
class HasNameValidator < ActiveModel::Validator
|
221
214
|
def validate(record)
|
222
|
-
record.errors
|
215
|
+
record.errors.add(:name, "must exist") if record.name.blank?
|
223
216
|
end
|
224
217
|
end
|
225
218
|
|
@@ -242,11 +235,11 @@ behavior out of the box:
|
|
242
235
|
|
243
236
|
The latest version of Active Model can be installed with RubyGems:
|
244
237
|
|
245
|
-
|
238
|
+
$ gem install activemodel
|
246
239
|
|
247
240
|
Source code can be downloaded as part of the Rails project on GitHub
|
248
241
|
|
249
|
-
* https://github.com/rails/rails/tree/
|
242
|
+
* https://github.com/rails/rails/tree/5-0-stable/activemodel
|
250
243
|
|
251
244
|
|
252
245
|
== License
|
@@ -269,4 +262,3 @@ Bug reports can be filed for the Ruby on Rails project here:
|
|
269
262
|
Feature requests should be discussed on the rails-core mailing list here:
|
270
263
|
|
271
264
|
* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core
|
272
|
-
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'active_support/core_ext/hash/keys'
|
2
|
+
|
3
|
+
module ActiveModel
|
4
|
+
module AttributeAssignment
|
5
|
+
include ActiveModel::ForbiddenAttributesProtection
|
6
|
+
|
7
|
+
# Allows you to set all the attributes by passing in a hash of attributes with
|
8
|
+
# keys matching the attribute names.
|
9
|
+
#
|
10
|
+
# If the passed hash responds to <tt>permitted?</tt> method and the return value
|
11
|
+
# of this method is +false+ an <tt>ActiveModel::ForbiddenAttributesError</tt>
|
12
|
+
# exception is raised.
|
13
|
+
#
|
14
|
+
# class Cat
|
15
|
+
# include ActiveModel::AttributeAssignment
|
16
|
+
# attr_accessor :name, :status
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# cat = Cat.new
|
20
|
+
# cat.assign_attributes(name: "Gorby", status: "yawning")
|
21
|
+
# cat.name # => 'Gorby'
|
22
|
+
# cat.status => 'yawning'
|
23
|
+
# cat.assign_attributes(status: "sleeping")
|
24
|
+
# cat.name # => 'Gorby'
|
25
|
+
# cat.status => 'sleeping'
|
26
|
+
def assign_attributes(new_attributes)
|
27
|
+
if !new_attributes.respond_to?(:stringify_keys)
|
28
|
+
raise ArgumentError, "When assigning attributes, you must pass a hash as an argument."
|
29
|
+
end
|
30
|
+
return if new_attributes.nil? || new_attributes.empty?
|
31
|
+
|
32
|
+
attributes = new_attributes.stringify_keys
|
33
|
+
_assign_attributes(sanitize_for_mass_assignment(attributes))
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def _assign_attributes(attributes)
|
39
|
+
attributes.each do |k, v|
|
40
|
+
_assign_attribute(k, v)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def _assign_attribute(k, v)
|
45
|
+
if respond_to?("#{k}=")
|
46
|
+
public_send("#{k}=", v)
|
47
|
+
else
|
48
|
+
raise UnknownAttributeError.new(self, k)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'concurrent/map'
|
2
2
|
require 'mutex_m'
|
3
3
|
|
4
4
|
module ActiveModel
|
@@ -23,7 +23,7 @@ module ActiveModel
|
|
23
23
|
# The requirements to implement <tt>ActiveModel::AttributeMethods</tt> are to:
|
24
24
|
#
|
25
25
|
# * <tt>include ActiveModel::AttributeMethods</tt> in your class.
|
26
|
-
# * Call each of its
|
26
|
+
# * Call each of its methods you want to add, such as +attribute_method_suffix+
|
27
27
|
# or +attribute_method_prefix+.
|
28
28
|
# * Call +define_attribute_methods+ after the other methods are called.
|
29
29
|
# * Define the various generic +_attribute+ methods that you have declared.
|
@@ -225,9 +225,9 @@ module ActiveModel
|
|
225
225
|
end
|
226
226
|
|
227
227
|
# Declares the attributes that should be prefixed and suffixed by
|
228
|
-
# ActiveModel::AttributeMethods
|
228
|
+
# <tt>ActiveModel::AttributeMethods</tt>.
|
229
229
|
#
|
230
|
-
# To use, pass attribute names (as strings or symbols)
|
230
|
+
# To use, pass attribute names (as strings or symbols). Be sure to declare
|
231
231
|
# +define_attribute_methods+ after you define any prefix, suffix or affix
|
232
232
|
# methods, or they will not hook in.
|
233
233
|
#
|
@@ -239,7 +239,7 @@ module ActiveModel
|
|
239
239
|
#
|
240
240
|
# # Call to define_attribute_methods must appear after the
|
241
241
|
# # attribute_method_prefix, attribute_method_suffix or
|
242
|
-
# # attribute_method_affix
|
242
|
+
# # attribute_method_affix declarations.
|
243
243
|
# define_attribute_methods :name, :age, :address
|
244
244
|
#
|
245
245
|
# private
|
@@ -253,9 +253,9 @@ module ActiveModel
|
|
253
253
|
end
|
254
254
|
|
255
255
|
# Declares an attribute that should be prefixed and suffixed by
|
256
|
-
# ActiveModel::AttributeMethods
|
256
|
+
# <tt>ActiveModel::AttributeMethods</tt>.
|
257
257
|
#
|
258
|
-
# To use, pass an attribute name (as string or symbol)
|
258
|
+
# To use, pass an attribute name (as string or symbol). Be sure to declare
|
259
259
|
# +define_attribute_method+ after you define any prefix, suffix or affix
|
260
260
|
# method, or they will not hook in.
|
261
261
|
#
|
@@ -267,7 +267,7 @@ module ActiveModel
|
|
267
267
|
#
|
268
268
|
# # Call to define_attribute_method must appear after the
|
269
269
|
# # attribute_method_prefix, attribute_method_suffix or
|
270
|
-
# # attribute_method_affix
|
270
|
+
# # attribute_method_affix declarations.
|
271
271
|
# define_attribute_method :name
|
272
272
|
#
|
273
273
|
# private
|
@@ -342,7 +342,7 @@ module ActiveModel
|
|
342
342
|
private
|
343
343
|
# The methods +method_missing+ and +respond_to?+ of this module are
|
344
344
|
# invoked often in a typical rails, both of which invoke the method
|
345
|
-
# +
|
345
|
+
# +matched_attribute_method+. The latter method iterates through an
|
346
346
|
# array doing regular expression matches, which results in a lot of
|
347
347
|
# object creations. Most of the time it returns a +nil+ match. As the
|
348
348
|
# match result is always the same given a +method_name+, this cache is
|
@@ -350,7 +350,7 @@ module ActiveModel
|
|
350
350
|
# significantly (in our case our test suite finishes 10% faster with
|
351
351
|
# this cache).
|
352
352
|
def attribute_method_matchers_cache #:nodoc:
|
353
|
-
@attribute_method_matchers_cache ||=
|
353
|
+
@attribute_method_matchers_cache ||= Concurrent::Map.new(initial_capacity: 4)
|
354
354
|
end
|
355
355
|
|
356
356
|
def attribute_method_matchers_matching(method_name) #:nodoc:
|
@@ -363,7 +363,7 @@ module ActiveModel
|
|
363
363
|
end
|
364
364
|
|
365
365
|
# Define a method `name` in `mod` that dispatches to `send`
|
366
|
-
# using the given `extra` args. This
|
366
|
+
# using the given `extra` args. This falls back on `define_method`
|
367
367
|
# and `send` if the given names cannot be compiled.
|
368
368
|
def define_proxy_call(include_private, mod, name, send, *extra) #:nodoc:
|
369
369
|
defn = if name =~ NAME_COMPILABLE_REGEXP
|
@@ -372,7 +372,7 @@ module ActiveModel
|
|
372
372
|
"define_method(:'#{name}') do |*args|"
|
373
373
|
end
|
374
374
|
|
375
|
-
extra = (extra.map!(&:inspect) << "*args").join(", ")
|
375
|
+
extra = (extra.map!(&:inspect) << "*args").join(", ".freeze)
|
376
376
|
|
377
377
|
target = if send =~ CALL_COMPILABLE_REGEXP
|
378
378
|
"#{"self." unless include_private}#{send}(#{extra})"
|
@@ -419,7 +419,7 @@ module ActiveModel
|
|
419
419
|
# returned by <tt>attributes</tt>, as though they were first-class
|
420
420
|
# methods. So a +Person+ class with a +name+ attribute can for example use
|
421
421
|
# <tt>Person#name</tt> and <tt>Person#name=</tt> and never directly use
|
422
|
-
# the attributes hash -- except for multiple
|
422
|
+
# the attributes hash -- except for multiple assignments with
|
423
423
|
# <tt>ActiveRecord::Base#attributes=</tt>.
|
424
424
|
#
|
425
425
|
# It's also possible to instantiate related objects, so a <tt>Client</tt>
|
@@ -429,7 +429,7 @@ module ActiveModel
|
|
429
429
|
if respond_to_without_attributes?(method, true)
|
430
430
|
super
|
431
431
|
else
|
432
|
-
match =
|
432
|
+
match = matched_attribute_method(method.to_s)
|
433
433
|
match ? attribute_missing(match, *args, &block) : super
|
434
434
|
end
|
435
435
|
end
|
@@ -454,7 +454,7 @@ module ActiveModel
|
|
454
454
|
# but found among all methods. Which means that the given method is private.
|
455
455
|
false
|
456
456
|
else
|
457
|
-
!
|
457
|
+
!matched_attribute_method(method.to_s).nil?
|
458
458
|
end
|
459
459
|
end
|
460
460
|
|
@@ -466,7 +466,7 @@ module ActiveModel
|
|
466
466
|
private
|
467
467
|
# Returns a struct representing the matching attribute method.
|
468
468
|
# The struct's attributes are prefix, base and suffix.
|
469
|
-
def
|
469
|
+
def matched_attribute_method(method_name)
|
470
470
|
matches = self.class.send(:attribute_method_matchers_matching, method_name)
|
471
471
|
matches.detect { |match| attribute_method?(match.attr_name) }
|
472
472
|
end
|
@@ -6,7 +6,7 @@ module ActiveModel
|
|
6
6
|
# Provides an interface for any class to have Active Record like callbacks.
|
7
7
|
#
|
8
8
|
# Like the Active Record methods, the callback chain is aborted as soon as
|
9
|
-
# one of the methods
|
9
|
+
# one of the methods throws +:abort+.
|
10
10
|
#
|
11
11
|
# First, extend ActiveModel::Callbacks from the class you are creating:
|
12
12
|
#
|
@@ -49,7 +49,7 @@ module ActiveModel
|
|
49
49
|
# puts 'block successfully called.'
|
50
50
|
# end
|
51
51
|
#
|
52
|
-
# You can choose
|
52
|
+
# You can choose to have only specific callbacks by passing a hash to the
|
53
53
|
# +define_model_callbacks+ method.
|
54
54
|
#
|
55
55
|
# define_model_callbacks :create, only: [:after, :before]
|
@@ -103,7 +103,7 @@ module ActiveModel
|
|
103
103
|
def define_model_callbacks(*callbacks)
|
104
104
|
options = callbacks.extract_options!
|
105
105
|
options = {
|
106
|
-
terminator:
|
106
|
+
terminator: deprecated_false_terminator,
|
107
107
|
skip_after_callbacks_if_terminated: true,
|
108
108
|
scope: [:kind, :name],
|
109
109
|
only: [:before, :around, :after]
|
@@ -22,7 +22,7 @@ module ActiveModel
|
|
22
22
|
module Conversion
|
23
23
|
extend ActiveSupport::Concern
|
24
24
|
|
25
|
-
# If your object is already designed to implement all of the Active Model
|
25
|
+
# If your object is already designed to implement all of the \Active \Model
|
26
26
|
# you can use the default <tt>:to_model</tt> implementation, which simply
|
27
27
|
# returns +self+.
|
28
28
|
#
|
@@ -33,15 +33,15 @@ module ActiveModel
|
|
33
33
|
# person = Person.new
|
34
34
|
# person.to_model == person # => true
|
35
35
|
#
|
36
|
-
# If your model does not act like an Active Model object, then you should
|
36
|
+
# If your model does not act like an \Active \Model object, then you should
|
37
37
|
# define <tt>:to_model</tt> yourself returning a proxy object that wraps
|
38
|
-
# your object with Active Model compliant methods.
|
38
|
+
# your object with \Active \Model compliant methods.
|
39
39
|
def to_model
|
40
40
|
self
|
41
41
|
end
|
42
42
|
|
43
|
-
# Returns an Array of all key attributes if any is set,
|
44
|
-
# the object is persisted
|
43
|
+
# Returns an Array of all key attributes if any of the attributes is set, whether or not
|
44
|
+
# the object is persisted. Returns +nil+ if there are no key attributes.
|
45
45
|
#
|
46
46
|
# class Person
|
47
47
|
# include ActiveModel::Conversion
|