activemodel 5.1.7 → 5.2.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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +32 -93
- data/README.rdoc +1 -1
- data/lib/active_model.rb +6 -1
- data/lib/active_model/attribute.rb +243 -0
- data/lib/active_model/attribute/user_provided_default.rb +30 -0
- data/lib/active_model/attribute_assignment.rb +8 -5
- data/lib/active_model/attribute_methods.rb +12 -10
- data/lib/active_model/attribute_mutation_tracker.rb +116 -0
- data/lib/active_model/attribute_set.rb +113 -0
- data/lib/active_model/attribute_set/builder.rb +124 -0
- data/lib/active_model/attribute_set/yaml_encoder.rb +41 -0
- data/lib/active_model/attributes.rb +108 -0
- data/lib/active_model/callbacks.rb +7 -2
- data/lib/active_model/conversion.rb +2 -0
- data/lib/active_model/dirty.rb +124 -57
- data/lib/active_model/errors.rb +32 -21
- data/lib/active_model/forbidden_attributes_protection.rb +2 -0
- data/lib/active_model/gem_version.rb +5 -3
- data/lib/active_model/lint.rb +2 -0
- data/lib/active_model/model.rb +2 -0
- data/lib/active_model/naming.rb +5 -3
- data/lib/active_model/railtie.rb +2 -0
- data/lib/active_model/secure_password.rb +5 -3
- data/lib/active_model/serialization.rb +2 -0
- data/lib/active_model/serializers/json.rb +3 -2
- data/lib/active_model/translation.rb +2 -0
- data/lib/active_model/type.rb +6 -0
- data/lib/active_model/type/big_integer.rb +2 -0
- data/lib/active_model/type/binary.rb +2 -0
- data/lib/active_model/type/boolean.rb +2 -0
- data/lib/active_model/type/date.rb +2 -0
- data/lib/active_model/type/date_time.rb +6 -0
- data/lib/active_model/type/decimal.rb +2 -0
- data/lib/active_model/type/float.rb +2 -0
- data/lib/active_model/type/helpers.rb +2 -0
- data/lib/active_model/type/helpers/accepts_multiparameter_time.rb +6 -0
- data/lib/active_model/type/helpers/mutable.rb +2 -0
- data/lib/active_model/type/helpers/numeric.rb +2 -0
- data/lib/active_model/type/helpers/time_value.rb +2 -1
- data/lib/active_model/type/immutable_string.rb +2 -0
- data/lib/active_model/type/integer.rb +3 -1
- data/lib/active_model/type/registry.rb +2 -0
- data/lib/active_model/type/string.rb +2 -0
- data/lib/active_model/type/time.rb +8 -4
- data/lib/active_model/type/value.rb +3 -1
- data/lib/active_model/validations.rb +7 -3
- data/lib/active_model/validations/absence.rb +2 -0
- data/lib/active_model/validations/acceptance.rb +2 -0
- data/lib/active_model/validations/callbacks.rb +11 -13
- data/lib/active_model/validations/clusivity.rb +2 -0
- data/lib/active_model/validations/confirmation.rb +3 -1
- data/lib/active_model/validations/exclusion.rb +2 -0
- data/lib/active_model/validations/format.rb +1 -0
- data/lib/active_model/validations/helper_methods.rb +2 -0
- data/lib/active_model/validations/inclusion.rb +2 -0
- data/lib/active_model/validations/length.rb +10 -2
- data/lib/active_model/validations/numericality.rb +3 -1
- data/lib/active_model/validations/presence.rb +1 -0
- data/lib/active_model/validations/validates.rb +4 -3
- data/lib/active_model/validations/with.rb +2 -0
- data/lib/active_model/validator.rb +6 -4
- data/lib/active_model/version.rb +2 -0
- metadata +17 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9a527b6fc9e7656a84868c763aec48bb368d7bfd
|
4
|
+
data.tar.gz: 4c6ebab7e83916520a612437380b074e002f37e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0671a93f14567ade18a581e3e0c848771e002261eccddcb703aa0b77f9574c1a2d2e091f2f295cafc37ce20e220dc01488b99e14653fb10d4415f4658c5396fb
|
7
|
+
data.tar.gz: 1385ef9675c0c9fd44b6acd88f55d3a25db8c0a5e42607b5ae12908e883aea9882c2fa42bcee5e50e585f1c46e023629878ef3bc40764ccb473efc32c81aaec4
|
data/CHANGELOG.md
CHANGED
@@ -1,112 +1,51 @@
|
|
1
|
-
## Rails 5.
|
1
|
+
## Rails 5.2.0.beta1 (November 27, 2017) ##
|
2
2
|
|
3
|
-
*
|
3
|
+
* Execute `ConfirmationValidator` validation when `_confirmation`'s value is `false`.
|
4
4
|
|
5
|
+
*bogdanvlviv*
|
5
6
|
|
6
|
-
|
7
|
+
* Allow passing a Proc or Symbol to length validator options.
|
7
8
|
|
8
|
-
*
|
9
|
+
*Matt Rohrer*
|
9
10
|
|
11
|
+
* Add method `#merge!` for `ActiveModel::Errors`.
|
10
12
|
|
11
|
-
|
13
|
+
*Jahfer Husain*
|
12
14
|
|
13
|
-
*
|
14
|
-
|
15
|
-
|
16
|
-
## Rails 5.1.6 (March 29, 2018) ##
|
17
|
-
|
18
|
-
* No changes.
|
19
|
-
|
20
|
-
|
21
|
-
## Rails 5.1.5 (February 14, 2018) ##
|
22
|
-
|
23
|
-
* Fix to working before/after validation callbacks on multiple contexts.
|
24
|
-
|
25
|
-
*Yoshiyuki Hirano*
|
26
|
-
|
27
|
-
## Rails 5.1.4 (September 07, 2017) ##
|
28
|
-
|
29
|
-
* No changes.
|
30
|
-
|
31
|
-
|
32
|
-
## Rails 5.1.4.rc1 (August 24, 2017) ##
|
33
|
-
|
34
|
-
* No changes.
|
35
|
-
|
36
|
-
|
37
|
-
## Rails 5.1.3 (August 03, 2017) ##
|
38
|
-
|
39
|
-
* No changes.
|
40
|
-
|
41
|
-
|
42
|
-
## Rails 5.1.3.rc3 (July 31, 2017) ##
|
43
|
-
|
44
|
-
* No changes.
|
45
|
-
|
46
|
-
|
47
|
-
## Rails 5.1.3.rc2 (July 25, 2017) ##
|
48
|
-
|
49
|
-
* No changes.
|
50
|
-
|
51
|
-
|
52
|
-
## Rails 5.1.3.rc1 (July 19, 2017) ##
|
53
|
-
|
54
|
-
* No changes.
|
55
|
-
|
56
|
-
|
57
|
-
## Rails 5.1.2 (June 26, 2017) ##
|
58
|
-
|
59
|
-
* Fix regression in numericality validator when comparing Decimal and Float input
|
15
|
+
* Fix regression in numericality validator when comparing Decimal and Float input
|
60
16
|
values with more scale than the schema.
|
61
17
|
|
62
18
|
*Bradley Priest*
|
63
19
|
|
20
|
+
* Fix methods `#keys`, `#values` in `ActiveModel::Errors`.
|
64
21
|
|
65
|
-
|
66
|
-
|
67
|
-
* No changes.
|
68
|
-
|
69
|
-
|
70
|
-
## Rails 5.1.0 (April 27, 2017) ##
|
71
|
-
|
72
|
-
* The original string assigned to a model attribute is no longer incorrectly
|
73
|
-
frozen.
|
74
|
-
|
75
|
-
Fixes #24185, #28718.
|
76
|
-
|
77
|
-
*Matthew Draper*
|
78
|
-
|
79
|
-
* Avoid converting integer as a string into float.
|
80
|
-
|
81
|
-
*namusyaka*
|
82
|
-
|
83
|
-
* Remove deprecated behavior that halts callbacks when the return is false.
|
84
|
-
|
85
|
-
*Rafael Mendonça França*
|
86
|
-
|
87
|
-
* Remove unused `ActiveModel::TestCase` class.
|
88
|
-
|
89
|
-
*Yuji Yaginuma*
|
90
|
-
|
91
|
-
* Moved DecimalWithoutScale, Text, and UnsignedInteger from Active Model to Active Record
|
92
|
-
|
93
|
-
*Iain Beeston*
|
94
|
-
|
95
|
-
* Allow indifferent access in `ActiveModel::Errors`.
|
96
|
-
|
97
|
-
`#include?`, `#has_key?`, `#key?`, `#delete` and `#full_messages_for`.
|
98
|
-
|
99
|
-
*Kenichi Kamiya*
|
22
|
+
Change `#keys` to only return the keys that don't have empty messages.
|
100
23
|
|
101
|
-
|
24
|
+
Change `#values` to only return the not empty values.
|
102
25
|
|
103
|
-
|
26
|
+
Example:
|
104
27
|
|
105
|
-
|
28
|
+
# Before
|
29
|
+
person = Person.new
|
30
|
+
person.errors.keys # => []
|
31
|
+
person.errors.values # => []
|
32
|
+
person.errors.messages # => {}
|
33
|
+
person.errors[:name] # => []
|
34
|
+
person.errors.messages # => {:name => []}
|
35
|
+
person.errors.keys # => [:name]
|
36
|
+
person.errors.values # => [[]]
|
106
37
|
|
107
|
-
|
38
|
+
# After
|
39
|
+
person = Person.new
|
40
|
+
person.errors.keys # => []
|
41
|
+
person.errors.values # => []
|
42
|
+
person.errors.messages # => {}
|
43
|
+
person.errors[:name] # => []
|
44
|
+
person.errors.messages # => {:name => []}
|
45
|
+
person.errors.keys # => []
|
46
|
+
person.errors.values # => []
|
108
47
|
|
109
|
-
*
|
48
|
+
*bogdanvlviv*
|
110
49
|
|
111
50
|
|
112
|
-
Please check [5-
|
51
|
+
Please check [5-1-stable](https://github.com/rails/rails/blob/5-1-stable/activemodel/CHANGELOG.md) for previous changes.
|
data/README.rdoc
CHANGED
data/lib/active_model.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#--
|
2
4
|
# Copyright (c) 2004-2017 David Heinemeier Hansson
|
3
5
|
#
|
@@ -28,6 +30,8 @@ require "active_model/version"
|
|
28
30
|
module ActiveModel
|
29
31
|
extend ActiveSupport::Autoload
|
30
32
|
|
33
|
+
autoload :Attribute
|
34
|
+
autoload :Attributes
|
31
35
|
autoload :AttributeAssignment
|
32
36
|
autoload :AttributeMethods
|
33
37
|
autoload :BlockValidator, "active_model/validator"
|
@@ -43,6 +47,7 @@ module ActiveModel
|
|
43
47
|
autoload :SecurePassword
|
44
48
|
autoload :Serialization
|
45
49
|
autoload :Translation
|
50
|
+
autoload :Type
|
46
51
|
autoload :Validations
|
47
52
|
autoload :Validator
|
48
53
|
|
@@ -68,5 +73,5 @@ module ActiveModel
|
|
68
73
|
end
|
69
74
|
|
70
75
|
ActiveSupport.on_load(:i18n) do
|
71
|
-
I18n.load_path << File.
|
76
|
+
I18n.load_path << File.expand_path("active_model/locale/en.yml", __dir__)
|
72
77
|
end
|
@@ -0,0 +1,243 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/object/duplicable"
|
4
|
+
|
5
|
+
module ActiveModel
|
6
|
+
class Attribute # :nodoc:
|
7
|
+
class << self
|
8
|
+
def from_database(name, value, type)
|
9
|
+
FromDatabase.new(name, value, type)
|
10
|
+
end
|
11
|
+
|
12
|
+
def from_user(name, value, type, original_attribute = nil)
|
13
|
+
FromUser.new(name, value, type, original_attribute)
|
14
|
+
end
|
15
|
+
|
16
|
+
def with_cast_value(name, value, type)
|
17
|
+
WithCastValue.new(name, value, type)
|
18
|
+
end
|
19
|
+
|
20
|
+
def null(name)
|
21
|
+
Null.new(name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def uninitialized(name, type)
|
25
|
+
Uninitialized.new(name, type)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_reader :name, :value_before_type_cast, :type
|
30
|
+
|
31
|
+
# This method should not be called directly.
|
32
|
+
# Use #from_database or #from_user
|
33
|
+
def initialize(name, value_before_type_cast, type, original_attribute = nil)
|
34
|
+
@name = name
|
35
|
+
@value_before_type_cast = value_before_type_cast
|
36
|
+
@type = type
|
37
|
+
@original_attribute = original_attribute
|
38
|
+
end
|
39
|
+
|
40
|
+
def value
|
41
|
+
# `defined?` is cheaper than `||=` when we get back falsy values
|
42
|
+
@value = type_cast(value_before_type_cast) unless defined?(@value)
|
43
|
+
@value
|
44
|
+
end
|
45
|
+
|
46
|
+
def original_value
|
47
|
+
if assigned?
|
48
|
+
original_attribute.original_value
|
49
|
+
else
|
50
|
+
type_cast(value_before_type_cast)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def value_for_database
|
55
|
+
type.serialize(value)
|
56
|
+
end
|
57
|
+
|
58
|
+
def changed?
|
59
|
+
changed_from_assignment? || changed_in_place?
|
60
|
+
end
|
61
|
+
|
62
|
+
def changed_in_place?
|
63
|
+
has_been_read? && type.changed_in_place?(original_value_for_database, value)
|
64
|
+
end
|
65
|
+
|
66
|
+
def forgetting_assignment
|
67
|
+
with_value_from_database(value_for_database)
|
68
|
+
end
|
69
|
+
|
70
|
+
def with_value_from_user(value)
|
71
|
+
type.assert_valid_value(value)
|
72
|
+
self.class.from_user(name, value, type, original_attribute || self)
|
73
|
+
end
|
74
|
+
|
75
|
+
def with_value_from_database(value)
|
76
|
+
self.class.from_database(name, value, type)
|
77
|
+
end
|
78
|
+
|
79
|
+
def with_cast_value(value)
|
80
|
+
self.class.with_cast_value(name, value, type)
|
81
|
+
end
|
82
|
+
|
83
|
+
def with_type(type)
|
84
|
+
if changed_in_place?
|
85
|
+
with_value_from_user(value).with_type(type)
|
86
|
+
else
|
87
|
+
self.class.new(name, value_before_type_cast, type, original_attribute)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def type_cast(*)
|
92
|
+
raise NotImplementedError
|
93
|
+
end
|
94
|
+
|
95
|
+
def initialized?
|
96
|
+
true
|
97
|
+
end
|
98
|
+
|
99
|
+
def came_from_user?
|
100
|
+
false
|
101
|
+
end
|
102
|
+
|
103
|
+
def has_been_read?
|
104
|
+
defined?(@value)
|
105
|
+
end
|
106
|
+
|
107
|
+
def ==(other)
|
108
|
+
self.class == other.class &&
|
109
|
+
name == other.name &&
|
110
|
+
value_before_type_cast == other.value_before_type_cast &&
|
111
|
+
type == other.type
|
112
|
+
end
|
113
|
+
alias eql? ==
|
114
|
+
|
115
|
+
def hash
|
116
|
+
[self.class, name, value_before_type_cast, type].hash
|
117
|
+
end
|
118
|
+
|
119
|
+
def init_with(coder)
|
120
|
+
@name = coder["name"]
|
121
|
+
@value_before_type_cast = coder["value_before_type_cast"]
|
122
|
+
@type = coder["type"]
|
123
|
+
@original_attribute = coder["original_attribute"]
|
124
|
+
@value = coder["value"] if coder.map.key?("value")
|
125
|
+
end
|
126
|
+
|
127
|
+
def encode_with(coder)
|
128
|
+
coder["name"] = name
|
129
|
+
coder["value_before_type_cast"] = value_before_type_cast unless value_before_type_cast.nil?
|
130
|
+
coder["type"] = type if type
|
131
|
+
coder["original_attribute"] = original_attribute if original_attribute
|
132
|
+
coder["value"] = value if defined?(@value)
|
133
|
+
end
|
134
|
+
|
135
|
+
protected
|
136
|
+
|
137
|
+
attr_reader :original_attribute
|
138
|
+
alias_method :assigned?, :original_attribute
|
139
|
+
|
140
|
+
def original_value_for_database
|
141
|
+
if assigned?
|
142
|
+
original_attribute.original_value_for_database
|
143
|
+
else
|
144
|
+
_original_value_for_database
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
private
|
149
|
+
def initialize_dup(other)
|
150
|
+
if defined?(@value) && @value.duplicable?
|
151
|
+
@value = @value.dup
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def changed_from_assignment?
|
156
|
+
assigned? && type.changed?(original_value, value, value_before_type_cast)
|
157
|
+
end
|
158
|
+
|
159
|
+
def _original_value_for_database
|
160
|
+
type.serialize(original_value)
|
161
|
+
end
|
162
|
+
|
163
|
+
class FromDatabase < Attribute # :nodoc:
|
164
|
+
def type_cast(value)
|
165
|
+
type.deserialize(value)
|
166
|
+
end
|
167
|
+
|
168
|
+
def _original_value_for_database
|
169
|
+
value_before_type_cast
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
class FromUser < Attribute # :nodoc:
|
174
|
+
def type_cast(value)
|
175
|
+
type.cast(value)
|
176
|
+
end
|
177
|
+
|
178
|
+
def came_from_user?
|
179
|
+
!type.value_constructed_by_mass_assignment?(value_before_type_cast)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
class WithCastValue < Attribute # :nodoc:
|
184
|
+
def type_cast(value)
|
185
|
+
value
|
186
|
+
end
|
187
|
+
|
188
|
+
def changed_in_place?
|
189
|
+
false
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
class Null < Attribute # :nodoc:
|
194
|
+
def initialize(name)
|
195
|
+
super(name, nil, Type.default_value)
|
196
|
+
end
|
197
|
+
|
198
|
+
def type_cast(*)
|
199
|
+
nil
|
200
|
+
end
|
201
|
+
|
202
|
+
def with_type(type)
|
203
|
+
self.class.with_cast_value(name, nil, type)
|
204
|
+
end
|
205
|
+
|
206
|
+
def with_value_from_database(value)
|
207
|
+
raise ActiveModel::MissingAttributeError, "can't write unknown attribute `#{name}`"
|
208
|
+
end
|
209
|
+
alias_method :with_value_from_user, :with_value_from_database
|
210
|
+
end
|
211
|
+
|
212
|
+
class Uninitialized < Attribute # :nodoc:
|
213
|
+
UNINITIALIZED_ORIGINAL_VALUE = Object.new
|
214
|
+
|
215
|
+
def initialize(name, type)
|
216
|
+
super(name, nil, type)
|
217
|
+
end
|
218
|
+
|
219
|
+
def value
|
220
|
+
if block_given?
|
221
|
+
yield name
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def original_value
|
226
|
+
UNINITIALIZED_ORIGINAL_VALUE
|
227
|
+
end
|
228
|
+
|
229
|
+
def value_for_database
|
230
|
+
end
|
231
|
+
|
232
|
+
def initialized?
|
233
|
+
false
|
234
|
+
end
|
235
|
+
|
236
|
+
def with_type(type)
|
237
|
+
self.class.new(name, type)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
private_constant :FromDatabase, :FromUser, :Null, :Uninitialized, :WithCastValue
|
242
|
+
end
|
243
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_model/attribute"
|
4
|
+
|
5
|
+
module ActiveModel
|
6
|
+
class Attribute # :nodoc:
|
7
|
+
class UserProvidedDefault < FromUser # :nodoc:
|
8
|
+
def initialize(name, value, type, database_default)
|
9
|
+
@user_provided_value = value
|
10
|
+
super(name, value, type, database_default)
|
11
|
+
end
|
12
|
+
|
13
|
+
def value_before_type_cast
|
14
|
+
if user_provided_value.is_a?(Proc)
|
15
|
+
@memoized_value_before_type_cast ||= user_provided_value.call
|
16
|
+
else
|
17
|
+
@user_provided_value
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def with_type(type)
|
22
|
+
self.class.new(name, user_provided_value, type, original_attribute)
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
attr_reader :user_provided_value
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|