rbs_rails 0.4.1 → 0.5.0
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/.gitmodules +3 -0
- data/README.md +12 -0
- data/Rakefile +2 -1
- data/Steepfile +9 -1
- data/bin/add-type-params.rb +1 -1
- data/bin/postprocess.rb +1 -1
- data/bin/rbs +29 -2
- data/bin/rbs-prototype-rb.rb +54 -5
- data/lib/rbs_rails/active_record.rb +2 -0
- data/lib/rbs_rails/version.rb +1 -1
- metadata +4 -21
- data/assets/sig/action_controller.rbs +0 -49
- data/assets/sig/active_record.rbs +0 -137
- data/assets/sig/generated/actionpack.rbs +0 -11831
- data/assets/sig/generated/actionview.rbs +0 -10591
- data/assets/sig/generated/activejob.rbs +0 -1920
- data/assets/sig/generated/activemodel.rbs +0 -4214
- data/assets/sig/generated/activerecord-meta-programming.rbs +0 -98
- data/assets/sig/generated/activerecord.rbs +0 -24602
- data/assets/sig/generated/activesupport.rbs +0 -12613
- data/assets/sig/generated/railties.rbs +0 -4687
- data/assets/sig/patches/README.md +0 -4
- data/assets/sig/patches/for_actionpack.rbs +0 -74
- data/assets/sig/patches/for_actionview.rbs +0 -19
- data/assets/sig/patches/for_activemodel.rbs +0 -11
- data/assets/sig/patches/for_activerecord.rbs +0 -84
- data/assets/sig/patches/for_activesupport.rbs +0 -48
- data/assets/sig/patches/for_railties.rbs +0 -30
- data/bin/generate_rbs_from_rails_source_code.rb +0 -201
@@ -1,4214 +0,0 @@
|
|
1
|
-
module ActiveModel
|
2
|
-
class Attribute
|
3
|
-
class UserProvidedDefault < FromUser
|
4
|
-
# :nodoc:
|
5
|
-
# :nodoc:
|
6
|
-
def initialize: (untyped name, untyped value, untyped `type`, untyped database_default) -> untyped
|
7
|
-
|
8
|
-
def value_before_type_cast: () -> untyped
|
9
|
-
|
10
|
-
def with_type: (untyped `type`) -> untyped
|
11
|
-
|
12
|
-
def marshal_dump: () -> untyped
|
13
|
-
|
14
|
-
def marshal_load: (untyped values) -> untyped
|
15
|
-
|
16
|
-
attr_reader user_provided_value: untyped
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
module ActiveModel
|
22
|
-
class Attribute
|
23
|
-
def self.from_database: (untyped name, untyped value, untyped `type`) -> FromDatabase
|
24
|
-
|
25
|
-
def self.from_user: (untyped name, untyped value, untyped `type`, ?untyped? original_attribute) -> FromUser
|
26
|
-
|
27
|
-
def self.with_cast_value: (untyped name, untyped value, untyped `type`) -> WithCastValue
|
28
|
-
|
29
|
-
def self.null: (untyped name) -> Null
|
30
|
-
|
31
|
-
def self.uninitialized: (untyped name, untyped `type`) -> Uninitialized
|
32
|
-
|
33
|
-
attr_reader name: untyped
|
34
|
-
|
35
|
-
attr_reader value_before_type_cast: untyped
|
36
|
-
|
37
|
-
attr_reader type: untyped
|
38
|
-
|
39
|
-
# This method should not be called directly.
|
40
|
-
# Use #from_database or #from_user
|
41
|
-
def initialize: (untyped name, untyped value_before_type_cast, untyped `type`, ?untyped? original_attribute) -> untyped
|
42
|
-
|
43
|
-
def value: () -> untyped
|
44
|
-
|
45
|
-
def original_value: () -> untyped
|
46
|
-
|
47
|
-
def value_for_database: () -> untyped
|
48
|
-
|
49
|
-
def changed?: () -> untyped
|
50
|
-
|
51
|
-
def changed_in_place?: () -> untyped
|
52
|
-
|
53
|
-
def forgetting_assignment: () -> untyped
|
54
|
-
|
55
|
-
def with_value_from_user: (untyped value) -> untyped
|
56
|
-
|
57
|
-
def with_value_from_database: (untyped value) -> untyped
|
58
|
-
|
59
|
-
def with_cast_value: (untyped value) -> untyped
|
60
|
-
|
61
|
-
def with_type: (untyped `type`) -> untyped
|
62
|
-
|
63
|
-
def type_cast: () -> untyped
|
64
|
-
|
65
|
-
def initialized?: () -> ::TrueClass
|
66
|
-
|
67
|
-
def came_from_user?: () -> ::FalseClass
|
68
|
-
|
69
|
-
def has_been_read?: () -> untyped
|
70
|
-
|
71
|
-
def ==: (untyped other) -> untyped
|
72
|
-
|
73
|
-
alias eql? ==
|
74
|
-
|
75
|
-
def hash: () -> untyped
|
76
|
-
|
77
|
-
def init_with: (untyped coder) -> untyped
|
78
|
-
|
79
|
-
def encode_with: (untyped coder) -> untyped
|
80
|
-
|
81
|
-
def original_value_for_database: () -> untyped
|
82
|
-
|
83
|
-
attr_reader original_attribute: untyped
|
84
|
-
|
85
|
-
alias assigned? original_attribute
|
86
|
-
|
87
|
-
def initialize_dup: (untyped other) -> untyped
|
88
|
-
|
89
|
-
def changed_from_assignment?: () -> untyped
|
90
|
-
|
91
|
-
def _original_value_for_database: () -> untyped
|
92
|
-
|
93
|
-
class FromDatabase < Attribute
|
94
|
-
# :nodoc:
|
95
|
-
def type_cast: (untyped value) -> untyped
|
96
|
-
|
97
|
-
def _original_value_for_database: () -> untyped
|
98
|
-
end
|
99
|
-
|
100
|
-
class FromUser < Attribute
|
101
|
-
# :nodoc:
|
102
|
-
def type_cast: (untyped value) -> untyped
|
103
|
-
|
104
|
-
def came_from_user?: () -> untyped
|
105
|
-
end
|
106
|
-
|
107
|
-
class WithCastValue < Attribute
|
108
|
-
# :nodoc:
|
109
|
-
def type_cast: (untyped value) -> untyped
|
110
|
-
|
111
|
-
def changed_in_place?: () -> ::FalseClass
|
112
|
-
end
|
113
|
-
|
114
|
-
class Null < Attribute
|
115
|
-
# :nodoc:
|
116
|
-
def initialize: (untyped name) -> untyped
|
117
|
-
|
118
|
-
def type_cast: () -> nil
|
119
|
-
|
120
|
-
def with_type: (untyped `type`) -> untyped
|
121
|
-
|
122
|
-
def with_value_from_database: (untyped value) -> untyped
|
123
|
-
|
124
|
-
alias with_value_from_user with_value_from_database
|
125
|
-
|
126
|
-
alias with_cast_value with_value_from_database
|
127
|
-
end
|
128
|
-
|
129
|
-
class Uninitialized < Attribute
|
130
|
-
# :nodoc:
|
131
|
-
UNINITIALIZED_ORIGINAL_VALUE: untyped
|
132
|
-
|
133
|
-
def initialize: (untyped name, untyped `type`) -> untyped
|
134
|
-
|
135
|
-
def value: () { (untyped) -> untyped } -> untyped
|
136
|
-
|
137
|
-
def original_value: () -> untyped
|
138
|
-
|
139
|
-
def value_for_database: () -> nil
|
140
|
-
|
141
|
-
def initialized?: () -> ::FalseClass
|
142
|
-
|
143
|
-
def forgetting_assignment: () -> untyped
|
144
|
-
|
145
|
-
def with_type: (untyped `type`) -> untyped
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
module ActiveModel
|
151
|
-
module AttributeAssignment
|
152
|
-
include ActiveModel::ForbiddenAttributesProtection
|
153
|
-
|
154
|
-
# Allows you to set all the attributes by passing in a hash of attributes with
|
155
|
-
# keys matching the attribute names.
|
156
|
-
#
|
157
|
-
# If the passed hash responds to <tt>permitted?</tt> method and the return value
|
158
|
-
# of this method is +false+ an <tt>ActiveModel::ForbiddenAttributesError</tt>
|
159
|
-
# exception is raised.
|
160
|
-
#
|
161
|
-
# class Cat
|
162
|
-
# include ActiveModel::AttributeAssignment
|
163
|
-
# attr_accessor :name, :status
|
164
|
-
# end
|
165
|
-
#
|
166
|
-
# cat = Cat.new
|
167
|
-
# cat.assign_attributes(name: "Gorby", status: "yawning")
|
168
|
-
# cat.name # => 'Gorby'
|
169
|
-
# cat.status # => 'yawning'
|
170
|
-
# cat.assign_attributes(status: "sleeping")
|
171
|
-
# cat.name # => 'Gorby'
|
172
|
-
# cat.status # => 'sleeping'
|
173
|
-
def assign_attributes: (untyped new_attributes) -> (nil | untyped)
|
174
|
-
|
175
|
-
alias attributes= assign_attributes
|
176
|
-
|
177
|
-
def _assign_attributes: (untyped attributes) -> untyped
|
178
|
-
|
179
|
-
def _assign_attribute: (untyped k, untyped v) -> untyped
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
module ActiveModel
|
184
|
-
# Raised when an attribute is not defined.
|
185
|
-
#
|
186
|
-
# class User < ActiveRecord::Base
|
187
|
-
# has_many :pets
|
188
|
-
# end
|
189
|
-
#
|
190
|
-
# user = User.first
|
191
|
-
# user.pets.select(:id).first.user_id
|
192
|
-
# # => ActiveModel::MissingAttributeError: missing attribute: user_id
|
193
|
-
class MissingAttributeError[T] < NoMethodError[T]
|
194
|
-
end
|
195
|
-
|
196
|
-
# == Active \Model \Attribute \Methods
|
197
|
-
#
|
198
|
-
# Provides a way to add prefixes and suffixes to your methods as
|
199
|
-
# well as handling the creation of <tt>ActiveRecord::Base</tt>-like
|
200
|
-
# class methods such as +table_name+.
|
201
|
-
#
|
202
|
-
# The requirements to implement <tt>ActiveModel::AttributeMethods</tt> are to:
|
203
|
-
#
|
204
|
-
# * <tt>include ActiveModel::AttributeMethods</tt> in your class.
|
205
|
-
# * Call each of its methods you want to add, such as +attribute_method_suffix+
|
206
|
-
# or +attribute_method_prefix+.
|
207
|
-
# * Call +define_attribute_methods+ after the other methods are called.
|
208
|
-
# * Define the various generic +_attribute+ methods that you have declared.
|
209
|
-
# * Define an +attributes+ method which returns a hash with each
|
210
|
-
# attribute name in your model as hash key and the attribute value as hash value.
|
211
|
-
# Hash keys must be strings.
|
212
|
-
#
|
213
|
-
# A minimal implementation could be:
|
214
|
-
#
|
215
|
-
# class Person
|
216
|
-
# include ActiveModel::AttributeMethods
|
217
|
-
#
|
218
|
-
# attribute_method_affix prefix: 'reset_', suffix: '_to_default!'
|
219
|
-
# attribute_method_suffix '_contrived?'
|
220
|
-
# attribute_method_prefix 'clear_'
|
221
|
-
# define_attribute_methods :name
|
222
|
-
#
|
223
|
-
# attr_accessor :name
|
224
|
-
#
|
225
|
-
# def attributes
|
226
|
-
# { 'name' => @name }
|
227
|
-
# end
|
228
|
-
#
|
229
|
-
# private
|
230
|
-
#
|
231
|
-
# def attribute_contrived?(attr)
|
232
|
-
# true
|
233
|
-
# end
|
234
|
-
#
|
235
|
-
# def clear_attribute(attr)
|
236
|
-
# send("#{attr}=", nil)
|
237
|
-
# end
|
238
|
-
#
|
239
|
-
# def reset_attribute_to_default!(attr)
|
240
|
-
# send("#{attr}=", 'Default Name')
|
241
|
-
# end
|
242
|
-
# end
|
243
|
-
module AttributeMethods
|
244
|
-
extend ActiveSupport::Concern
|
245
|
-
|
246
|
-
NAME_COMPILABLE_REGEXP: untyped
|
247
|
-
|
248
|
-
CALL_COMPILABLE_REGEXP: untyped
|
249
|
-
|
250
|
-
module ClassMethods
|
251
|
-
# Declares a method available for all attributes with the given prefix.
|
252
|
-
# Uses +method_missing+ and <tt>respond_to?</tt> to rewrite the method.
|
253
|
-
#
|
254
|
-
# #{prefix}#{attr}(*args, &block)
|
255
|
-
#
|
256
|
-
# to
|
257
|
-
#
|
258
|
-
# #{prefix}attribute(#{attr}, *args, &block)
|
259
|
-
#
|
260
|
-
# An instance method <tt>#{prefix}attribute</tt> must exist and accept
|
261
|
-
# at least the +attr+ argument.
|
262
|
-
#
|
263
|
-
# class Person
|
264
|
-
# include ActiveModel::AttributeMethods
|
265
|
-
#
|
266
|
-
# attr_accessor :name
|
267
|
-
# attribute_method_prefix 'clear_'
|
268
|
-
# define_attribute_methods :name
|
269
|
-
#
|
270
|
-
# private
|
271
|
-
#
|
272
|
-
# def clear_attribute(attr)
|
273
|
-
# send("#{attr}=", nil)
|
274
|
-
# end
|
275
|
-
# end
|
276
|
-
#
|
277
|
-
# person = Person.new
|
278
|
-
# person.name = 'Bob'
|
279
|
-
# person.name # => "Bob"
|
280
|
-
# person.clear_name
|
281
|
-
# person.name # => nil
|
282
|
-
def attribute_method_prefix: (*untyped prefixes) -> untyped
|
283
|
-
|
284
|
-
# Declares a method available for all attributes with the given suffix.
|
285
|
-
# Uses +method_missing+ and <tt>respond_to?</tt> to rewrite the method.
|
286
|
-
#
|
287
|
-
# #{attr}#{suffix}(*args, &block)
|
288
|
-
#
|
289
|
-
# to
|
290
|
-
#
|
291
|
-
# attribute#{suffix}(#{attr}, *args, &block)
|
292
|
-
#
|
293
|
-
# An <tt>attribute#{suffix}</tt> instance method must exist and accept at
|
294
|
-
# least the +attr+ argument.
|
295
|
-
#
|
296
|
-
# class Person
|
297
|
-
# include ActiveModel::AttributeMethods
|
298
|
-
#
|
299
|
-
# attr_accessor :name
|
300
|
-
# attribute_method_suffix '_short?'
|
301
|
-
# define_attribute_methods :name
|
302
|
-
#
|
303
|
-
# private
|
304
|
-
#
|
305
|
-
# def attribute_short?(attr)
|
306
|
-
# send(attr).length < 5
|
307
|
-
# end
|
308
|
-
# end
|
309
|
-
#
|
310
|
-
# person = Person.new
|
311
|
-
# person.name = 'Bob'
|
312
|
-
# person.name # => "Bob"
|
313
|
-
# person.name_short? # => true
|
314
|
-
def attribute_method_suffix: (*untyped suffixes) -> untyped
|
315
|
-
|
316
|
-
# Declares a method available for all attributes with the given prefix
|
317
|
-
# and suffix. Uses +method_missing+ and <tt>respond_to?</tt> to rewrite
|
318
|
-
# the method.
|
319
|
-
#
|
320
|
-
# #{prefix}#{attr}#{suffix}(*args, &block)
|
321
|
-
#
|
322
|
-
# to
|
323
|
-
#
|
324
|
-
# #{prefix}attribute#{suffix}(#{attr}, *args, &block)
|
325
|
-
#
|
326
|
-
# An <tt>#{prefix}attribute#{suffix}</tt> instance method must exist and
|
327
|
-
# accept at least the +attr+ argument.
|
328
|
-
#
|
329
|
-
# class Person
|
330
|
-
# include ActiveModel::AttributeMethods
|
331
|
-
#
|
332
|
-
# attr_accessor :name
|
333
|
-
# attribute_method_affix prefix: 'reset_', suffix: '_to_default!'
|
334
|
-
# define_attribute_methods :name
|
335
|
-
#
|
336
|
-
# private
|
337
|
-
#
|
338
|
-
# def reset_attribute_to_default!(attr)
|
339
|
-
# send("#{attr}=", 'Default Name')
|
340
|
-
# end
|
341
|
-
# end
|
342
|
-
#
|
343
|
-
# person = Person.new
|
344
|
-
# person.name # => 'Gem'
|
345
|
-
# person.reset_name_to_default!
|
346
|
-
# person.name # => 'Default Name'
|
347
|
-
def attribute_method_affix: (*untyped affixes) -> untyped
|
348
|
-
|
349
|
-
# Allows you to make aliases for attributes.
|
350
|
-
#
|
351
|
-
# class Person
|
352
|
-
# include ActiveModel::AttributeMethods
|
353
|
-
#
|
354
|
-
# attr_accessor :name
|
355
|
-
# attribute_method_suffix '_short?'
|
356
|
-
# define_attribute_methods :name
|
357
|
-
#
|
358
|
-
# alias_attribute :nickname, :name
|
359
|
-
#
|
360
|
-
# private
|
361
|
-
#
|
362
|
-
# def attribute_short?(attr)
|
363
|
-
# send(attr).length < 5
|
364
|
-
# end
|
365
|
-
# end
|
366
|
-
#
|
367
|
-
# person = Person.new
|
368
|
-
# person.name = 'Bob'
|
369
|
-
# person.name # => "Bob"
|
370
|
-
# person.nickname # => "Bob"
|
371
|
-
# person.name_short? # => true
|
372
|
-
# person.nickname_short? # => true
|
373
|
-
def alias_attribute: (untyped new_name, untyped old_name) -> untyped
|
374
|
-
|
375
|
-
# Is +new_name+ an alias?
|
376
|
-
def attribute_alias?: (untyped new_name) -> untyped
|
377
|
-
|
378
|
-
# Returns the original name for the alias +name+
|
379
|
-
def attribute_alias: (untyped name) -> untyped
|
380
|
-
|
381
|
-
# Declares the attributes that should be prefixed and suffixed by
|
382
|
-
# <tt>ActiveModel::AttributeMethods</tt>.
|
383
|
-
#
|
384
|
-
# To use, pass attribute names (as strings or symbols). Be sure to declare
|
385
|
-
# +define_attribute_methods+ after you define any prefix, suffix or affix
|
386
|
-
# methods, or they will not hook in.
|
387
|
-
#
|
388
|
-
# class Person
|
389
|
-
# include ActiveModel::AttributeMethods
|
390
|
-
#
|
391
|
-
# attr_accessor :name, :age, :address
|
392
|
-
# attribute_method_prefix 'clear_'
|
393
|
-
#
|
394
|
-
# # Call to define_attribute_methods must appear after the
|
395
|
-
# # attribute_method_prefix, attribute_method_suffix or
|
396
|
-
# # attribute_method_affix declarations.
|
397
|
-
# define_attribute_methods :name, :age, :address
|
398
|
-
#
|
399
|
-
# private
|
400
|
-
#
|
401
|
-
# def clear_attribute(attr)
|
402
|
-
# send("#{attr}=", nil)
|
403
|
-
# end
|
404
|
-
# end
|
405
|
-
def define_attribute_methods: (*untyped attr_names) -> untyped
|
406
|
-
|
407
|
-
# Declares an attribute that should be prefixed and suffixed by
|
408
|
-
# <tt>ActiveModel::AttributeMethods</tt>.
|
409
|
-
#
|
410
|
-
# To use, pass an attribute name (as string or symbol). Be sure to declare
|
411
|
-
# +define_attribute_method+ after you define any prefix, suffix or affix
|
412
|
-
# method, or they will not hook in.
|
413
|
-
#
|
414
|
-
# class Person
|
415
|
-
# include ActiveModel::AttributeMethods
|
416
|
-
#
|
417
|
-
# attr_accessor :name
|
418
|
-
# attribute_method_suffix '_short?'
|
419
|
-
#
|
420
|
-
# # Call to define_attribute_method must appear after the
|
421
|
-
# # attribute_method_prefix, attribute_method_suffix or
|
422
|
-
# # attribute_method_affix declarations.
|
423
|
-
# define_attribute_method :name
|
424
|
-
#
|
425
|
-
# private
|
426
|
-
#
|
427
|
-
# def attribute_short?(attr)
|
428
|
-
# send(attr).length < 5
|
429
|
-
# end
|
430
|
-
# end
|
431
|
-
#
|
432
|
-
# person = Person.new
|
433
|
-
# person.name = 'Bob'
|
434
|
-
# person.name # => "Bob"
|
435
|
-
# person.name_short? # => true
|
436
|
-
def define_attribute_method: (untyped attr_name) -> untyped
|
437
|
-
|
438
|
-
# Removes all the previously dynamically defined methods from the class.
|
439
|
-
#
|
440
|
-
# class Person
|
441
|
-
# include ActiveModel::AttributeMethods
|
442
|
-
#
|
443
|
-
# attr_accessor :name
|
444
|
-
# attribute_method_suffix '_short?'
|
445
|
-
# define_attribute_method :name
|
446
|
-
#
|
447
|
-
# private
|
448
|
-
#
|
449
|
-
# def attribute_short?(attr)
|
450
|
-
# send(attr).length < 5
|
451
|
-
# end
|
452
|
-
# end
|
453
|
-
#
|
454
|
-
# person = Person.new
|
455
|
-
# person.name = 'Bob'
|
456
|
-
# person.name_short? # => true
|
457
|
-
#
|
458
|
-
# Person.undefine_attribute_methods
|
459
|
-
#
|
460
|
-
# person.name_short? # => NoMethodError
|
461
|
-
def undefine_attribute_methods: () -> untyped
|
462
|
-
|
463
|
-
def generated_attribute_methods: () -> untyped
|
464
|
-
|
465
|
-
def instance_method_already_implemented?: (untyped method_name) -> untyped
|
466
|
-
|
467
|
-
# The methods +method_missing+ and +respond_to?+ of this module are
|
468
|
-
# invoked often in a typical rails, both of which invoke the method
|
469
|
-
# +matched_attribute_method+. The latter method iterates through an
|
470
|
-
# array doing regular expression matches, which results in a lot of
|
471
|
-
# object creations. Most of the time it returns a +nil+ match. As the
|
472
|
-
# match result is always the same given a +method_name+, this cache is
|
473
|
-
# used to alleviate the GC, which ultimately also speeds up the app
|
474
|
-
# significantly (in our case our test suite finishes 10% faster with
|
475
|
-
# this cache).
|
476
|
-
def attribute_method_matchers_cache: () -> untyped
|
477
|
-
|
478
|
-
def attribute_method_matchers_matching: (untyped method_name) -> untyped
|
479
|
-
|
480
|
-
# Define a method `name` in `mod` that dispatches to `send`
|
481
|
-
# using the given `extra` args. This falls back on `define_method`
|
482
|
-
# and `send` if the given names cannot be compiled.
|
483
|
-
def define_proxy_call: (untyped include_private, untyped mod, untyped name, untyped target, *untyped extra) -> untyped
|
484
|
-
|
485
|
-
class AttributeMethodMatcher
|
486
|
-
# nodoc:
|
487
|
-
attr_reader prefix: untyped
|
488
|
-
|
489
|
-
# nodoc:
|
490
|
-
attr_reader suffix: untyped
|
491
|
-
|
492
|
-
# nodoc:
|
493
|
-
attr_reader target: untyped
|
494
|
-
|
495
|
-
class AttributeMethodMatch[T] < ::Struct[T]
|
496
|
-
attr_accessor target(): untyped
|
497
|
-
|
498
|
-
attr_accessor attr_name(): untyped
|
499
|
-
end
|
500
|
-
|
501
|
-
def initialize: (?::Hash[untyped, untyped] options) -> untyped
|
502
|
-
|
503
|
-
def match: (untyped method_name) -> untyped
|
504
|
-
|
505
|
-
def method_name: (untyped attr_name) -> untyped
|
506
|
-
|
507
|
-
def plain?: () -> untyped
|
508
|
-
end
|
509
|
-
end
|
510
|
-
|
511
|
-
# Allows access to the object attributes, which are held in the hash
|
512
|
-
# returned by <tt>attributes</tt>, as though they were first-class
|
513
|
-
# methods. So a +Person+ class with a +name+ attribute can for example use
|
514
|
-
# <tt>Person#name</tt> and <tt>Person#name=</tt> and never directly use
|
515
|
-
# the attributes hash -- except for multiple assignments with
|
516
|
-
# <tt>ActiveRecord::Base#attributes=</tt>.
|
517
|
-
#
|
518
|
-
# It's also possible to instantiate related objects, so a <tt>Client</tt>
|
519
|
-
# class belonging to the +clients+ table with a +master_id+ foreign key
|
520
|
-
# can instantiate master through <tt>Client#master</tt>.
|
521
|
-
def method_missing: (untyped method, *untyped args) { () -> untyped } -> untyped
|
522
|
-
|
523
|
-
# +attribute_missing+ is like +method_missing+, but for attributes. When
|
524
|
-
# +method_missing+ is called we check to see if there is a matching
|
525
|
-
# attribute method. If so, we tell +attribute_missing+ to dispatch the
|
526
|
-
# attribute. This method can be overloaded to customize the behavior.
|
527
|
-
def attribute_missing: (untyped match, *untyped args) { () -> untyped } -> untyped
|
528
|
-
|
529
|
-
# A +Person+ instance with a +name+ attribute can ask
|
530
|
-
# <tt>person.respond_to?(:name)</tt>, <tt>person.respond_to?(:name=)</tt>,
|
531
|
-
# and <tt>person.respond_to?(:name?)</tt> which will all return +true+.
|
532
|
-
alias respond_to_without_attributes? respond_to?
|
533
|
-
|
534
|
-
def respond_to?: (untyped method, ?bool include_private_methods) -> untyped
|
535
|
-
|
536
|
-
def attribute_method?: (untyped attr_name) -> untyped
|
537
|
-
|
538
|
-
# Returns a struct representing the matching attribute method.
|
539
|
-
# The struct's attributes are prefix, base and suffix.
|
540
|
-
def matched_attribute_method: (untyped method_name) -> untyped
|
541
|
-
|
542
|
-
def missing_attribute: (untyped attr_name, untyped stack) -> untyped
|
543
|
-
|
544
|
-
def _read_attribute: (untyped attr) -> untyped
|
545
|
-
|
546
|
-
module AttrNames
|
547
|
-
# :nodoc:
|
548
|
-
DEF_SAFE_NAME: untyped
|
549
|
-
|
550
|
-
# We want to generate the methods via module_eval rather than
|
551
|
-
# define_method, because define_method is slower on dispatch.
|
552
|
-
# Evaluating many similar methods may use more memory as the instruction
|
553
|
-
# sequences are duplicated and cached (in MRI). define_method may
|
554
|
-
# be slower on dispatch, but if you're careful about the closure
|
555
|
-
# created, then define_method will consume much less memory.
|
556
|
-
#
|
557
|
-
# But sometimes the database might return columns with
|
558
|
-
# characters that are not allowed in normal method names (like
|
559
|
-
# 'my_column(omg)'. So to work around this we first define with
|
560
|
-
# the __temp__ identifier, and then use alias method to rename
|
561
|
-
# it to what we want.
|
562
|
-
#
|
563
|
-
# We are also defining a constant to hold the frozen string of
|
564
|
-
# the attribute name. Using a constant means that we do not have
|
565
|
-
# to allocate an object on each call to the attribute method.
|
566
|
-
# Making it frozen means that it doesn't get duped when used to
|
567
|
-
# key the @attributes in read_attribute.
|
568
|
-
def self.define_attribute_accessor_method: (untyped mod, untyped attr_name, ?writer: bool writer) { (untyped, untyped) -> untyped } -> untyped
|
569
|
-
end
|
570
|
-
end
|
571
|
-
end
|
572
|
-
|
573
|
-
module ActiveModel
|
574
|
-
class AttributeMutationTracker
|
575
|
-
# :nodoc:
|
576
|
-
OPTION_NOT_GIVEN: untyped
|
577
|
-
|
578
|
-
def initialize: (untyped attributes, ?untyped forced_changes) -> untyped
|
579
|
-
|
580
|
-
def changed_attribute_names: () -> untyped
|
581
|
-
|
582
|
-
def changed_values: () -> untyped
|
583
|
-
|
584
|
-
def changes: () -> untyped
|
585
|
-
|
586
|
-
def change_to_attribute: (untyped attr_name) -> untyped
|
587
|
-
|
588
|
-
def any_changes?: () -> untyped
|
589
|
-
|
590
|
-
def changed?: (untyped attr_name, ?from: untyped from, ?to: untyped to) -> untyped
|
591
|
-
|
592
|
-
def changed_in_place?: (untyped attr_name) -> untyped
|
593
|
-
|
594
|
-
def forget_change: (untyped attr_name) -> untyped
|
595
|
-
|
596
|
-
def original_value: (untyped attr_name) -> untyped
|
597
|
-
|
598
|
-
def force_change: (untyped attr_name) -> untyped
|
599
|
-
|
600
|
-
attr_reader attributes: untyped
|
601
|
-
|
602
|
-
attr_reader forced_changes: untyped
|
603
|
-
|
604
|
-
def attr_names: () -> untyped
|
605
|
-
|
606
|
-
def attribute_changed?: (untyped attr_name) -> untyped
|
607
|
-
|
608
|
-
def fetch_value: (untyped attr_name) -> untyped
|
609
|
-
end
|
610
|
-
|
611
|
-
class ForcedMutationTracker < AttributeMutationTracker
|
612
|
-
# :nodoc:
|
613
|
-
def initialize: (untyped attributes, ?::Hash[untyped, untyped] forced_changes) -> untyped
|
614
|
-
|
615
|
-
def changed_in_place?: (untyped attr_name) -> ::FalseClass
|
616
|
-
|
617
|
-
def change_to_attribute: (untyped attr_name) -> untyped
|
618
|
-
|
619
|
-
def forget_change: (untyped attr_name) -> untyped
|
620
|
-
|
621
|
-
def original_value: (untyped attr_name) -> untyped
|
622
|
-
|
623
|
-
def force_change: (untyped attr_name) -> untyped
|
624
|
-
|
625
|
-
def finalize_changes: () -> untyped
|
626
|
-
|
627
|
-
attr_reader finalized_changes: untyped
|
628
|
-
|
629
|
-
def attr_names: () -> untyped
|
630
|
-
|
631
|
-
def attribute_changed?: (untyped attr_name) -> untyped
|
632
|
-
|
633
|
-
def fetch_value: (untyped attr_name) -> untyped
|
634
|
-
|
635
|
-
def clone_value: (untyped attr_name) -> untyped
|
636
|
-
end
|
637
|
-
|
638
|
-
class NullMutationTracker
|
639
|
-
# :nodoc:
|
640
|
-
include Singleton
|
641
|
-
|
642
|
-
def changed_attribute_names: () -> ::Array[untyped]
|
643
|
-
|
644
|
-
def changed_values: () -> ::Hash[untyped, untyped]
|
645
|
-
|
646
|
-
def changes: () -> ::Hash[untyped, untyped]
|
647
|
-
|
648
|
-
def change_to_attribute: (untyped attr_name) -> nil
|
649
|
-
|
650
|
-
def any_changes?: () -> ::FalseClass
|
651
|
-
|
652
|
-
def changed?: (untyped attr_name) -> ::FalseClass
|
653
|
-
|
654
|
-
def changed_in_place?: (untyped attr_name) -> ::FalseClass
|
655
|
-
|
656
|
-
def original_value: (untyped attr_name) -> nil
|
657
|
-
end
|
658
|
-
end
|
659
|
-
|
660
|
-
module ActiveModel
|
661
|
-
class AttributeSet
|
662
|
-
class Builder
|
663
|
-
# :nodoc:
|
664
|
-
# :nodoc:
|
665
|
-
attr_reader types: untyped
|
666
|
-
|
667
|
-
# :nodoc:
|
668
|
-
# :nodoc:
|
669
|
-
attr_reader default_attributes: untyped
|
670
|
-
|
671
|
-
def initialize: (untyped types, ?::Hash[untyped, untyped] default_attributes) -> untyped
|
672
|
-
|
673
|
-
def build_from_database: (?::Hash[untyped, untyped] values, ?::Hash[untyped, untyped] additional_types) -> AttributeSet
|
674
|
-
end
|
675
|
-
end
|
676
|
-
|
677
|
-
class LazyAttributeHash
|
678
|
-
def initialize: (untyped types, untyped values, untyped additional_types, untyped default_attributes, ?::Hash[untyped, untyped] delegate_hash) -> untyped
|
679
|
-
|
680
|
-
def key?: (untyped key) -> untyped
|
681
|
-
|
682
|
-
def []: (untyped key) -> untyped
|
683
|
-
|
684
|
-
def []=: (untyped key, untyped value) -> untyped
|
685
|
-
|
686
|
-
def deep_dup: () -> untyped
|
687
|
-
|
688
|
-
def initialize_dup: (untyped _) -> untyped
|
689
|
-
|
690
|
-
def select: () { (untyped, untyped) -> untyped } -> untyped
|
691
|
-
|
692
|
-
def ==: (untyped other) -> untyped
|
693
|
-
|
694
|
-
def marshal_dump: () -> ::Array[untyped]
|
695
|
-
|
696
|
-
def marshal_load: (untyped values) -> untyped
|
697
|
-
|
698
|
-
def materialize: () -> untyped
|
699
|
-
|
700
|
-
attr_reader types: untyped
|
701
|
-
|
702
|
-
attr_reader values: untyped
|
703
|
-
|
704
|
-
attr_reader additional_types: untyped
|
705
|
-
|
706
|
-
attr_reader delegate_hash: untyped
|
707
|
-
|
708
|
-
attr_reader default_attributes: untyped
|
709
|
-
|
710
|
-
def assign_default_value: (untyped name) -> untyped
|
711
|
-
end
|
712
|
-
end
|
713
|
-
|
714
|
-
module ActiveModel
|
715
|
-
class AttributeSet
|
716
|
-
class YAMLEncoder
|
717
|
-
# Attempts to do more intelligent YAML dumping of an
|
718
|
-
# ActiveModel::AttributeSet to reduce the size of the resulting string
|
719
|
-
# :nodoc:
|
720
|
-
def initialize: (untyped default_types) -> untyped
|
721
|
-
|
722
|
-
def encode: (untyped attribute_set, untyped coder) -> untyped
|
723
|
-
|
724
|
-
def decode: (untyped coder) -> untyped
|
725
|
-
|
726
|
-
attr_reader default_types: untyped
|
727
|
-
end
|
728
|
-
end
|
729
|
-
end
|
730
|
-
|
731
|
-
module ActiveModel
|
732
|
-
class AttributeSet
|
733
|
-
def initialize: (untyped attributes) -> untyped
|
734
|
-
|
735
|
-
def []: (untyped name) -> untyped
|
736
|
-
|
737
|
-
def []=: (untyped name, untyped value) -> untyped
|
738
|
-
|
739
|
-
def values_before_type_cast: () -> untyped
|
740
|
-
|
741
|
-
def to_hash: () -> untyped
|
742
|
-
|
743
|
-
alias to_h to_hash
|
744
|
-
|
745
|
-
def key?: (untyped name) -> untyped
|
746
|
-
|
747
|
-
def keys: () -> untyped
|
748
|
-
|
749
|
-
def fetch_value: (untyped name) { () -> untyped } -> untyped
|
750
|
-
|
751
|
-
def write_from_database: (untyped name, untyped value) -> untyped
|
752
|
-
|
753
|
-
def write_from_user: (untyped name, untyped value) -> untyped
|
754
|
-
|
755
|
-
def write_cast_value: (untyped name, untyped value) -> untyped
|
756
|
-
|
757
|
-
def freeze: () -> untyped
|
758
|
-
|
759
|
-
def deep_dup: () -> untyped
|
760
|
-
|
761
|
-
def initialize_dup: (untyped _) -> untyped
|
762
|
-
|
763
|
-
def initialize_clone: (untyped _) -> untyped
|
764
|
-
|
765
|
-
def reset: (untyped key) -> untyped
|
766
|
-
|
767
|
-
def accessed: () -> untyped
|
768
|
-
|
769
|
-
def map: () { () -> untyped } -> AttributeSet
|
770
|
-
|
771
|
-
def ==: (untyped other) -> untyped
|
772
|
-
|
773
|
-
attr_reader attributes: untyped
|
774
|
-
|
775
|
-
def initialized_attributes: () -> untyped
|
776
|
-
end
|
777
|
-
end
|
778
|
-
|
779
|
-
module ActiveModel
|
780
|
-
module Attributes
|
781
|
-
# nodoc:
|
782
|
-
extend ActiveSupport::Concern
|
783
|
-
|
784
|
-
include ActiveModel::AttributeMethods
|
785
|
-
|
786
|
-
extend ::ActiveModel::AttributeMethods::ClassMethods
|
787
|
-
|
788
|
-
module ClassMethods
|
789
|
-
def attribute: (untyped name, ?untyped `type`, **untyped options) -> untyped
|
790
|
-
|
791
|
-
# Returns an array of attribute names as strings
|
792
|
-
#
|
793
|
-
# class Person
|
794
|
-
# include ActiveModel::Attributes
|
795
|
-
#
|
796
|
-
# attribute :name, :string
|
797
|
-
# attribute :age, :integer
|
798
|
-
# end
|
799
|
-
#
|
800
|
-
# Person.attribute_names
|
801
|
-
# # => ["name", "age"]
|
802
|
-
def attribute_names: () -> untyped
|
803
|
-
|
804
|
-
def define_method_attribute=: (untyped name) -> untyped
|
805
|
-
|
806
|
-
NO_DEFAULT_PROVIDED: untyped
|
807
|
-
|
808
|
-
def define_default_attribute: (untyped name, untyped value, untyped `type`) -> untyped
|
809
|
-
end
|
810
|
-
|
811
|
-
def initialize: () -> untyped
|
812
|
-
|
813
|
-
# Returns a hash of all the attributes with their names as keys and the values of the attributes as values.
|
814
|
-
#
|
815
|
-
# class Person
|
816
|
-
# include ActiveModel::Model
|
817
|
-
# include ActiveModel::Attributes
|
818
|
-
#
|
819
|
-
# attribute :name, :string
|
820
|
-
# attribute :age, :integer
|
821
|
-
# end
|
822
|
-
#
|
823
|
-
# person = Person.new(name: 'Francesco', age: 22)
|
824
|
-
# person.attributes
|
825
|
-
# # => {"name"=>"Francesco", "age"=>22}
|
826
|
-
def attributes: () -> untyped
|
827
|
-
|
828
|
-
# Returns an array of attribute names as strings
|
829
|
-
#
|
830
|
-
# class Person
|
831
|
-
# include ActiveModel::Attributes
|
832
|
-
#
|
833
|
-
# attribute :name, :string
|
834
|
-
# attribute :age, :integer
|
835
|
-
# end
|
836
|
-
#
|
837
|
-
# person = Person.new
|
838
|
-
# person.attribute_names
|
839
|
-
# # => ["name", "age"]
|
840
|
-
def attribute_names: () -> untyped
|
841
|
-
|
842
|
-
def write_attribute: (untyped attr_name, untyped value) -> untyped
|
843
|
-
|
844
|
-
def attribute: (untyped attr_name) -> untyped
|
845
|
-
|
846
|
-
# Dispatch target for <tt>*=</tt> attribute methods.
|
847
|
-
def attribute=: (untyped attribute_name, untyped value) -> untyped
|
848
|
-
end
|
849
|
-
end
|
850
|
-
|
851
|
-
module ActiveModel
|
852
|
-
# == Active \Model \Callbacks
|
853
|
-
#
|
854
|
-
# Provides an interface for any class to have Active Record like callbacks.
|
855
|
-
#
|
856
|
-
# Like the Active Record methods, the callback chain is aborted as soon as
|
857
|
-
# one of the methods throws +:abort+.
|
858
|
-
#
|
859
|
-
# First, extend ActiveModel::Callbacks from the class you are creating:
|
860
|
-
#
|
861
|
-
# class MyModel
|
862
|
-
# extend ActiveModel::Callbacks
|
863
|
-
# end
|
864
|
-
#
|
865
|
-
# Then define a list of methods that you want callbacks attached to:
|
866
|
-
#
|
867
|
-
# define_model_callbacks :create, :update
|
868
|
-
#
|
869
|
-
# This will provide all three standard callbacks (before, around and after)
|
870
|
-
# for both the <tt>:create</tt> and <tt>:update</tt> methods. To implement,
|
871
|
-
# you need to wrap the methods you want callbacks on in a block so that the
|
872
|
-
# callbacks get a chance to fire:
|
873
|
-
#
|
874
|
-
# def create
|
875
|
-
# run_callbacks :create do
|
876
|
-
# # Your create action methods here
|
877
|
-
# end
|
878
|
-
# end
|
879
|
-
#
|
880
|
-
# Then in your class, you can use the +before_create+, +after_create+ and
|
881
|
-
# +around_create+ methods, just as you would in an Active Record model.
|
882
|
-
#
|
883
|
-
# before_create :action_before_create
|
884
|
-
#
|
885
|
-
# def action_before_create
|
886
|
-
# # Your code here
|
887
|
-
# end
|
888
|
-
#
|
889
|
-
# When defining an around callback remember to yield to the block, otherwise
|
890
|
-
# it won't be executed:
|
891
|
-
#
|
892
|
-
# around_create :log_status
|
893
|
-
#
|
894
|
-
# def log_status
|
895
|
-
# puts 'going to call the block...'
|
896
|
-
# yield
|
897
|
-
# puts 'block successfully called.'
|
898
|
-
# end
|
899
|
-
#
|
900
|
-
# You can choose to have only specific callbacks by passing a hash to the
|
901
|
-
# +define_model_callbacks+ method.
|
902
|
-
#
|
903
|
-
# define_model_callbacks :create, only: [:after, :before]
|
904
|
-
#
|
905
|
-
# Would only create the +after_create+ and +before_create+ callback methods in
|
906
|
-
# your class.
|
907
|
-
#
|
908
|
-
# NOTE: Calling the same callback multiple times will overwrite previous callback definitions.
|
909
|
-
#
|
910
|
-
module Callbacks
|
911
|
-
def self.extended: (untyped base) -> untyped
|
912
|
-
|
913
|
-
# define_model_callbacks accepts the same options +define_callbacks+ does,
|
914
|
-
# in case you want to overwrite a default. Besides that, it also accepts an
|
915
|
-
# <tt>:only</tt> option, where you can choose if you want all types (before,
|
916
|
-
# around or after) or just some.
|
917
|
-
#
|
918
|
-
# define_model_callbacks :initializer, only: :after
|
919
|
-
#
|
920
|
-
# Note, the <tt>only: <type></tt> hash will apply to all callbacks defined
|
921
|
-
# on that method call. To get around this you can call the define_model_callbacks
|
922
|
-
# method as many times as you need.
|
923
|
-
#
|
924
|
-
# define_model_callbacks :create, only: :after
|
925
|
-
# define_model_callbacks :update, only: :before
|
926
|
-
# define_model_callbacks :destroy, only: :around
|
927
|
-
#
|
928
|
-
# Would create +after_create+, +before_update+ and +around_destroy+ methods
|
929
|
-
# only.
|
930
|
-
#
|
931
|
-
# You can pass in a class to before_<type>, after_<type> and around_<type>,
|
932
|
-
# in which case the callback will call that class's <action>_<type> method
|
933
|
-
# passing the object that the callback is being called on.
|
934
|
-
#
|
935
|
-
# class MyModel
|
936
|
-
# extend ActiveModel::Callbacks
|
937
|
-
# define_model_callbacks :create
|
938
|
-
#
|
939
|
-
# before_create AnotherClass
|
940
|
-
# end
|
941
|
-
#
|
942
|
-
# class AnotherClass
|
943
|
-
# def self.before_create( obj )
|
944
|
-
# # obj is the MyModel instance that the callback is being called on
|
945
|
-
# end
|
946
|
-
# end
|
947
|
-
#
|
948
|
-
# NOTE: +method_name+ passed to define_model_callbacks must not end with
|
949
|
-
# <tt>!</tt>, <tt>?</tt> or <tt>=</tt>.
|
950
|
-
def define_model_callbacks: (*untyped callbacks) -> untyped
|
951
|
-
|
952
|
-
def _define_before_model_callback: (untyped klass, untyped callback) -> untyped
|
953
|
-
|
954
|
-
def _define_around_model_callback: (untyped klass, untyped callback) -> untyped
|
955
|
-
|
956
|
-
def _define_after_model_callback: (untyped klass, untyped callback) -> untyped
|
957
|
-
end
|
958
|
-
end
|
959
|
-
|
960
|
-
module ActiveModel
|
961
|
-
# == Active \Model \Conversion
|
962
|
-
#
|
963
|
-
# Handles default conversions: to_model, to_key, to_param, and to_partial_path.
|
964
|
-
#
|
965
|
-
# Let's take for example this non-persisted object.
|
966
|
-
#
|
967
|
-
# class ContactMessage
|
968
|
-
# include ActiveModel::Conversion
|
969
|
-
#
|
970
|
-
# # ContactMessage are never persisted in the DB
|
971
|
-
# def persisted?
|
972
|
-
# false
|
973
|
-
# end
|
974
|
-
# end
|
975
|
-
#
|
976
|
-
# cm = ContactMessage.new
|
977
|
-
# cm.to_model == cm # => true
|
978
|
-
# cm.to_key # => nil
|
979
|
-
# cm.to_param # => nil
|
980
|
-
# cm.to_partial_path # => "contact_messages/contact_message"
|
981
|
-
module Conversion
|
982
|
-
extend ActiveSupport::Concern
|
983
|
-
|
984
|
-
# If your object is already designed to implement all of the \Active \Model
|
985
|
-
# you can use the default <tt>:to_model</tt> implementation, which simply
|
986
|
-
# returns +self+.
|
987
|
-
#
|
988
|
-
# class Person
|
989
|
-
# include ActiveModel::Conversion
|
990
|
-
# end
|
991
|
-
#
|
992
|
-
# person = Person.new
|
993
|
-
# person.to_model == person # => true
|
994
|
-
#
|
995
|
-
# If your model does not act like an \Active \Model object, then you should
|
996
|
-
# define <tt>:to_model</tt> yourself returning a proxy object that wraps
|
997
|
-
# your object with \Active \Model compliant methods.
|
998
|
-
def to_model: () -> untyped
|
999
|
-
|
1000
|
-
# Returns an Array of all key attributes if any of the attributes is set, whether or not
|
1001
|
-
# the object is persisted. Returns +nil+ if there are no key attributes.
|
1002
|
-
#
|
1003
|
-
# class Person
|
1004
|
-
# include ActiveModel::Conversion
|
1005
|
-
# attr_accessor :id
|
1006
|
-
#
|
1007
|
-
# def initialize(id)
|
1008
|
-
# @id = id
|
1009
|
-
# end
|
1010
|
-
# end
|
1011
|
-
#
|
1012
|
-
# person = Person.new(1)
|
1013
|
-
# person.to_key # => [1]
|
1014
|
-
def to_key: () -> untyped
|
1015
|
-
|
1016
|
-
# Returns a +string+ representing the object's key suitable for use in URLs,
|
1017
|
-
# or +nil+ if <tt>persisted?</tt> is +false+.
|
1018
|
-
#
|
1019
|
-
# class Person
|
1020
|
-
# include ActiveModel::Conversion
|
1021
|
-
# attr_accessor :id
|
1022
|
-
#
|
1023
|
-
# def initialize(id)
|
1024
|
-
# @id = id
|
1025
|
-
# end
|
1026
|
-
#
|
1027
|
-
# def persisted?
|
1028
|
-
# true
|
1029
|
-
# end
|
1030
|
-
# end
|
1031
|
-
#
|
1032
|
-
# person = Person.new(1)
|
1033
|
-
# person.to_param # => "1"
|
1034
|
-
def to_param: () -> untyped
|
1035
|
-
|
1036
|
-
# Returns a +string+ identifying the path associated with the object.
|
1037
|
-
# ActionPack uses this to find a suitable partial to represent the object.
|
1038
|
-
#
|
1039
|
-
# class Person
|
1040
|
-
# include ActiveModel::Conversion
|
1041
|
-
# end
|
1042
|
-
#
|
1043
|
-
# person = Person.new
|
1044
|
-
# person.to_partial_path # => "people/person"
|
1045
|
-
def to_partial_path: () -> untyped
|
1046
|
-
|
1047
|
-
module ClassMethods
|
1048
|
-
def _to_partial_path: () -> untyped
|
1049
|
-
end
|
1050
|
-
end
|
1051
|
-
end
|
1052
|
-
|
1053
|
-
module ActiveModel
|
1054
|
-
# == Active \Model \Dirty
|
1055
|
-
#
|
1056
|
-
# Provides a way to track changes in your object in the same way as
|
1057
|
-
# Active Record does.
|
1058
|
-
#
|
1059
|
-
# The requirements for implementing ActiveModel::Dirty are:
|
1060
|
-
#
|
1061
|
-
# * <tt>include ActiveModel::Dirty</tt> in your object.
|
1062
|
-
# * Call <tt>define_attribute_methods</tt> passing each method you want to
|
1063
|
-
# track.
|
1064
|
-
# * Call <tt>[attr_name]_will_change!</tt> before each change to the tracked
|
1065
|
-
# attribute.
|
1066
|
-
# * Call <tt>changes_applied</tt> after the changes are persisted.
|
1067
|
-
# * Call <tt>clear_changes_information</tt> when you want to reset the changes
|
1068
|
-
# information.
|
1069
|
-
# * Call <tt>restore_attributes</tt> when you want to restore previous data.
|
1070
|
-
#
|
1071
|
-
# A minimal implementation could be:
|
1072
|
-
#
|
1073
|
-
# class Person
|
1074
|
-
# include ActiveModel::Dirty
|
1075
|
-
#
|
1076
|
-
# define_attribute_methods :name
|
1077
|
-
#
|
1078
|
-
# def initialize
|
1079
|
-
# @name = nil
|
1080
|
-
# end
|
1081
|
-
#
|
1082
|
-
# def name
|
1083
|
-
# @name
|
1084
|
-
# end
|
1085
|
-
#
|
1086
|
-
# def name=(val)
|
1087
|
-
# name_will_change! unless val == @name
|
1088
|
-
# @name = val
|
1089
|
-
# end
|
1090
|
-
#
|
1091
|
-
# def save
|
1092
|
-
# # do persistence work
|
1093
|
-
#
|
1094
|
-
# changes_applied
|
1095
|
-
# end
|
1096
|
-
#
|
1097
|
-
# def reload!
|
1098
|
-
# # get the values from the persistence layer
|
1099
|
-
#
|
1100
|
-
# clear_changes_information
|
1101
|
-
# end
|
1102
|
-
#
|
1103
|
-
# def rollback!
|
1104
|
-
# restore_attributes
|
1105
|
-
# end
|
1106
|
-
# end
|
1107
|
-
#
|
1108
|
-
# A newly instantiated +Person+ object is unchanged:
|
1109
|
-
#
|
1110
|
-
# person = Person.new
|
1111
|
-
# person.changed? # => false
|
1112
|
-
#
|
1113
|
-
# Change the name:
|
1114
|
-
#
|
1115
|
-
# person.name = 'Bob'
|
1116
|
-
# person.changed? # => true
|
1117
|
-
# person.name_changed? # => true
|
1118
|
-
# person.name_changed?(from: nil, to: "Bob") # => true
|
1119
|
-
# person.name_was # => nil
|
1120
|
-
# person.name_change # => [nil, "Bob"]
|
1121
|
-
# person.name = 'Bill'
|
1122
|
-
# person.name_change # => [nil, "Bill"]
|
1123
|
-
#
|
1124
|
-
# Save the changes:
|
1125
|
-
#
|
1126
|
-
# person.save
|
1127
|
-
# person.changed? # => false
|
1128
|
-
# person.name_changed? # => false
|
1129
|
-
#
|
1130
|
-
# Reset the changes:
|
1131
|
-
#
|
1132
|
-
# person.previous_changes # => {"name" => [nil, "Bill"]}
|
1133
|
-
# person.name_previously_changed? # => true
|
1134
|
-
# person.name_previous_change # => [nil, "Bill"]
|
1135
|
-
# person.reload!
|
1136
|
-
# person.previous_changes # => {}
|
1137
|
-
#
|
1138
|
-
# Rollback the changes:
|
1139
|
-
#
|
1140
|
-
# person.name = "Uncle Bob"
|
1141
|
-
# person.rollback!
|
1142
|
-
# person.name # => "Bill"
|
1143
|
-
# person.name_changed? # => false
|
1144
|
-
#
|
1145
|
-
# Assigning the same value leaves the attribute unchanged:
|
1146
|
-
#
|
1147
|
-
# person.name = 'Bill'
|
1148
|
-
# person.name_changed? # => false
|
1149
|
-
# person.name_change # => nil
|
1150
|
-
#
|
1151
|
-
# Which attributes have changed?
|
1152
|
-
#
|
1153
|
-
# person.name = 'Bob'
|
1154
|
-
# person.changed # => ["name"]
|
1155
|
-
# person.changes # => {"name" => ["Bill", "Bob"]}
|
1156
|
-
#
|
1157
|
-
# If an attribute is modified in-place then make use of
|
1158
|
-
# <tt>[attribute_name]_will_change!</tt> to mark that the attribute is changing.
|
1159
|
-
# Otherwise \Active \Model can't track changes to in-place attributes. Note
|
1160
|
-
# that Active Record can detect in-place modifications automatically. You do
|
1161
|
-
# not need to call <tt>[attribute_name]_will_change!</tt> on Active Record models.
|
1162
|
-
#
|
1163
|
-
# person.name_will_change!
|
1164
|
-
# person.name_change # => ["Bill", "Bill"]
|
1165
|
-
# person.name << 'y'
|
1166
|
-
# person.name_change # => ["Bill", "Billy"]
|
1167
|
-
module Dirty
|
1168
|
-
extend ActiveSupport::Concern
|
1169
|
-
|
1170
|
-
include ActiveModel::AttributeMethods
|
1171
|
-
|
1172
|
-
extend ::ActiveModel::AttributeMethods::ClassMethods
|
1173
|
-
|
1174
|
-
def initialize_dup: (untyped other) -> untyped
|
1175
|
-
|
1176
|
-
# Clears dirty data and moves +changes+ to +previously_changed+ and
|
1177
|
-
# +mutations_from_database+ to +mutations_before_last_save+ respectively.
|
1178
|
-
def changes_applied: () -> untyped
|
1179
|
-
|
1180
|
-
# Returns +true+ if any of the attributes has unsaved changes, +false+ otherwise.
|
1181
|
-
#
|
1182
|
-
# person.changed? # => false
|
1183
|
-
# person.name = 'bob'
|
1184
|
-
# person.changed? # => true
|
1185
|
-
def changed?: () -> untyped
|
1186
|
-
|
1187
|
-
# Returns an array with the name of the attributes with unsaved changes.
|
1188
|
-
#
|
1189
|
-
# person.changed # => []
|
1190
|
-
# person.name = 'bob'
|
1191
|
-
# person.changed # => ["name"]
|
1192
|
-
def changed: () -> untyped
|
1193
|
-
|
1194
|
-
def attribute_changed?: (untyped attr_name, **untyped options) -> untyped
|
1195
|
-
|
1196
|
-
def attribute_was: (untyped attr_name) -> untyped
|
1197
|
-
|
1198
|
-
def attribute_previously_changed?: (untyped attr_name) -> untyped
|
1199
|
-
|
1200
|
-
# Restore all previous data of the provided attributes.
|
1201
|
-
def restore_attributes: (?untyped attr_names) -> untyped
|
1202
|
-
|
1203
|
-
# Clears all dirty data: current changes and previous changes.
|
1204
|
-
def clear_changes_information: () -> untyped
|
1205
|
-
|
1206
|
-
def clear_attribute_changes: (untyped attr_names) -> untyped
|
1207
|
-
|
1208
|
-
# Returns a hash of the attributes with unsaved changes indicating their original
|
1209
|
-
# values like <tt>attr => original value</tt>.
|
1210
|
-
#
|
1211
|
-
# person.name # => "bob"
|
1212
|
-
# person.name = 'robert'
|
1213
|
-
# person.changed_attributes # => {"name" => "bob"}
|
1214
|
-
def changed_attributes: () -> untyped
|
1215
|
-
|
1216
|
-
# Returns a hash of changed attributes indicating their original
|
1217
|
-
# and new values like <tt>attr => [original value, new value]</tt>.
|
1218
|
-
#
|
1219
|
-
# person.changes # => {}
|
1220
|
-
# person.name = 'bob'
|
1221
|
-
# person.changes # => { "name" => ["bill", "bob"] }
|
1222
|
-
def changes: () -> untyped
|
1223
|
-
|
1224
|
-
# Returns a hash of attributes that were changed before the model was saved.
|
1225
|
-
#
|
1226
|
-
# person.name # => "bob"
|
1227
|
-
# person.name = 'robert'
|
1228
|
-
# person.save
|
1229
|
-
# person.previous_changes # => {"name" => ["bob", "robert"]}
|
1230
|
-
def previous_changes: () -> untyped
|
1231
|
-
|
1232
|
-
def attribute_changed_in_place?: (untyped attr_name) -> untyped
|
1233
|
-
|
1234
|
-
def clear_attribute_change: (untyped attr_name) -> untyped
|
1235
|
-
|
1236
|
-
def mutations_from_database: () -> untyped
|
1237
|
-
|
1238
|
-
def forget_attribute_assignments: () -> untyped
|
1239
|
-
|
1240
|
-
def mutations_before_last_save: () -> untyped
|
1241
|
-
|
1242
|
-
# Dispatch target for <tt>*_change</tt> attribute methods.
|
1243
|
-
def attribute_change: (untyped attr_name) -> untyped
|
1244
|
-
|
1245
|
-
# Dispatch target for <tt>*_previous_change</tt> attribute methods.
|
1246
|
-
def attribute_previous_change: (untyped attr_name) -> untyped
|
1247
|
-
|
1248
|
-
# Dispatch target for <tt>*_will_change!</tt> attribute methods.
|
1249
|
-
def attribute_will_change!: (untyped attr_name) -> untyped
|
1250
|
-
|
1251
|
-
# Dispatch target for <tt>restore_*!</tt> attribute methods.
|
1252
|
-
def restore_attribute!: (untyped attr_name) -> untyped
|
1253
|
-
end
|
1254
|
-
end
|
1255
|
-
|
1256
|
-
module ActiveModel
|
1257
|
-
# == Active \Model \Errors
|
1258
|
-
#
|
1259
|
-
# Provides a modified +Hash+ that you can include in your object
|
1260
|
-
# for handling error messages and interacting with Action View helpers.
|
1261
|
-
#
|
1262
|
-
# A minimal implementation could be:
|
1263
|
-
#
|
1264
|
-
# class Person
|
1265
|
-
# # Required dependency for ActiveModel::Errors
|
1266
|
-
# extend ActiveModel::Naming
|
1267
|
-
#
|
1268
|
-
# def initialize
|
1269
|
-
# @errors = ActiveModel::Errors.new(self)
|
1270
|
-
# end
|
1271
|
-
#
|
1272
|
-
# attr_accessor :name
|
1273
|
-
# attr_reader :errors
|
1274
|
-
#
|
1275
|
-
# def validate!
|
1276
|
-
# errors.add(:name, :blank, message: "cannot be nil") if name.nil?
|
1277
|
-
# end
|
1278
|
-
#
|
1279
|
-
# # The following methods are needed to be minimally implemented
|
1280
|
-
#
|
1281
|
-
# def read_attribute_for_validation(attr)
|
1282
|
-
# send(attr)
|
1283
|
-
# end
|
1284
|
-
#
|
1285
|
-
# def self.human_attribute_name(attr, options = {})
|
1286
|
-
# attr
|
1287
|
-
# end
|
1288
|
-
#
|
1289
|
-
# def self.lookup_ancestors
|
1290
|
-
# [self]
|
1291
|
-
# end
|
1292
|
-
# end
|
1293
|
-
#
|
1294
|
-
# The last three methods are required in your object for +Errors+ to be
|
1295
|
-
# able to generate error messages correctly and also handle multiple
|
1296
|
-
# languages. Of course, if you extend your object with <tt>ActiveModel::Translation</tt>
|
1297
|
-
# you will not need to implement the last two. Likewise, using
|
1298
|
-
# <tt>ActiveModel::Validations</tt> will handle the validation related methods
|
1299
|
-
# for you.
|
1300
|
-
#
|
1301
|
-
# The above allows you to do:
|
1302
|
-
#
|
1303
|
-
# person = Person.new
|
1304
|
-
# person.validate! # => ["cannot be nil"]
|
1305
|
-
# person.errors.full_messages # => ["name cannot be nil"]
|
1306
|
-
# # etc..
|
1307
|
-
class Errors
|
1308
|
-
include Enumerable[untyped]
|
1309
|
-
|
1310
|
-
CALLBACKS_OPTIONS: ::Array[untyped]
|
1311
|
-
|
1312
|
-
MESSAGE_OPTIONS: ::Array[untyped]
|
1313
|
-
|
1314
|
-
attr_accessor i18n_customize_full_message: untyped
|
1315
|
-
|
1316
|
-
attr_reader messages: untyped
|
1317
|
-
|
1318
|
-
attr_reader details: untyped
|
1319
|
-
|
1320
|
-
# Pass in the instance of the object that is using the errors object.
|
1321
|
-
#
|
1322
|
-
# class Person
|
1323
|
-
# def initialize
|
1324
|
-
# @errors = ActiveModel::Errors.new(self)
|
1325
|
-
# end
|
1326
|
-
# end
|
1327
|
-
def initialize: (untyped base) -> untyped
|
1328
|
-
|
1329
|
-
def initialize_dup: (untyped other) -> untyped
|
1330
|
-
|
1331
|
-
def copy!: (untyped other) -> untyped
|
1332
|
-
|
1333
|
-
# Merges the errors from <tt>other</tt>.
|
1334
|
-
#
|
1335
|
-
# other - The ActiveModel::Errors instance.
|
1336
|
-
#
|
1337
|
-
# Examples
|
1338
|
-
#
|
1339
|
-
# person.errors.merge!(other)
|
1340
|
-
def merge!: (untyped other) -> untyped
|
1341
|
-
|
1342
|
-
# Removes all errors except the given keys. Returns a hash containing the removed errors.
|
1343
|
-
#
|
1344
|
-
# person.errors.keys # => [:name, :age, :gender, :city]
|
1345
|
-
# person.errors.slice!(:age, :gender) # => { :name=>["cannot be nil"], :city=>["cannot be nil"] }
|
1346
|
-
# person.errors.keys # => [:age, :gender]
|
1347
|
-
def slice!: (*untyped keys) -> untyped
|
1348
|
-
|
1349
|
-
# Clear the error messages.
|
1350
|
-
#
|
1351
|
-
# person.errors.full_messages # => ["name cannot be nil"]
|
1352
|
-
# person.errors.clear
|
1353
|
-
# person.errors.full_messages # => []
|
1354
|
-
def clear: () -> untyped
|
1355
|
-
|
1356
|
-
# Returns +true+ if the error messages include an error for the given key
|
1357
|
-
# +attribute+, +false+ otherwise.
|
1358
|
-
#
|
1359
|
-
# person.errors.messages # => {:name=>["cannot be nil"]}
|
1360
|
-
# person.errors.include?(:name) # => true
|
1361
|
-
# person.errors.include?(:age) # => false
|
1362
|
-
def include?: (untyped attribute) -> untyped
|
1363
|
-
|
1364
|
-
alias has_key? include?
|
1365
|
-
|
1366
|
-
alias key? include?
|
1367
|
-
|
1368
|
-
# Delete messages for +key+. Returns the deleted messages.
|
1369
|
-
#
|
1370
|
-
# person.errors[:name] # => ["cannot be nil"]
|
1371
|
-
# person.errors.delete(:name) # => ["cannot be nil"]
|
1372
|
-
# person.errors[:name] # => []
|
1373
|
-
def delete: (untyped key) -> untyped
|
1374
|
-
|
1375
|
-
# When passed a symbol or a name of a method, returns an array of errors
|
1376
|
-
# for the method.
|
1377
|
-
#
|
1378
|
-
# person.errors[:name] # => ["cannot be nil"]
|
1379
|
-
# person.errors['name'] # => ["cannot be nil"]
|
1380
|
-
def []: (untyped attribute) -> untyped
|
1381
|
-
|
1382
|
-
# Iterates through each error key, value pair in the error messages hash.
|
1383
|
-
# Yields the attribute and the error for that attribute. If the attribute
|
1384
|
-
# has more than one error message, yields once for each error message.
|
1385
|
-
#
|
1386
|
-
# person.errors.add(:name, :blank, message: "can't be blank")
|
1387
|
-
# person.errors.each do |attribute, error|
|
1388
|
-
# # Will yield :name and "can't be blank"
|
1389
|
-
# end
|
1390
|
-
#
|
1391
|
-
# person.errors.add(:name, :not_specified, message: "must be specified")
|
1392
|
-
# person.errors.each do |attribute, error|
|
1393
|
-
# # Will yield :name and "can't be blank"
|
1394
|
-
# # then yield :name and "must be specified"
|
1395
|
-
# end
|
1396
|
-
def each: () { (untyped, untyped) -> untyped } -> untyped
|
1397
|
-
|
1398
|
-
# Returns the number of error messages.
|
1399
|
-
#
|
1400
|
-
# person.errors.add(:name, :blank, message: "can't be blank")
|
1401
|
-
# person.errors.size # => 1
|
1402
|
-
# person.errors.add(:name, :not_specified, message: "must be specified")
|
1403
|
-
# person.errors.size # => 2
|
1404
|
-
def size: () -> untyped
|
1405
|
-
|
1406
|
-
alias count size
|
1407
|
-
|
1408
|
-
# Returns all message values.
|
1409
|
-
#
|
1410
|
-
# person.errors.messages # => {:name=>["cannot be nil", "must be specified"]}
|
1411
|
-
# person.errors.values # => [["cannot be nil", "must be specified"]]
|
1412
|
-
def values: () -> untyped
|
1413
|
-
|
1414
|
-
# Returns all message keys.
|
1415
|
-
#
|
1416
|
-
# person.errors.messages # => {:name=>["cannot be nil", "must be specified"]}
|
1417
|
-
# person.errors.keys # => [:name]
|
1418
|
-
def keys: () -> untyped
|
1419
|
-
|
1420
|
-
# Returns +true+ if no errors are found, +false+ otherwise.
|
1421
|
-
# If the error message is a string it can be empty.
|
1422
|
-
#
|
1423
|
-
# person.errors.full_messages # => ["name cannot be nil"]
|
1424
|
-
# person.errors.empty? # => false
|
1425
|
-
def empty?: () -> untyped
|
1426
|
-
|
1427
|
-
alias blank? empty?
|
1428
|
-
|
1429
|
-
# Returns an xml formatted representation of the Errors hash.
|
1430
|
-
#
|
1431
|
-
# person.errors.add(:name, :blank, message: "can't be blank")
|
1432
|
-
# person.errors.add(:name, :not_specified, message: "must be specified")
|
1433
|
-
# person.errors.to_xml
|
1434
|
-
# # =>
|
1435
|
-
# # <?xml version=\"1.0\" encoding=\"UTF-8\"?>
|
1436
|
-
# # <errors>
|
1437
|
-
# # <error>name can't be blank</error>
|
1438
|
-
# # <error>name must be specified</error>
|
1439
|
-
# # </errors>
|
1440
|
-
def to_xml: (?::Hash[untyped, untyped] options) -> untyped
|
1441
|
-
|
1442
|
-
# Returns a Hash that can be used as the JSON representation for this
|
1443
|
-
# object. You can pass the <tt>:full_messages</tt> option. This determines
|
1444
|
-
# if the json object should contain full messages or not (false by default).
|
1445
|
-
#
|
1446
|
-
# person.errors.as_json # => {:name=>["cannot be nil"]}
|
1447
|
-
# person.errors.as_json(full_messages: true) # => {:name=>["name cannot be nil"]}
|
1448
|
-
def as_json: (?untyped? options) -> untyped
|
1449
|
-
|
1450
|
-
# Returns a Hash of attributes with their error messages. If +full_messages+
|
1451
|
-
# is +true+, it will contain full messages (see +full_message+).
|
1452
|
-
#
|
1453
|
-
# person.errors.to_hash # => {:name=>["cannot be nil"]}
|
1454
|
-
# person.errors.to_hash(true) # => {:name=>["name cannot be nil"]}
|
1455
|
-
def to_hash: (?bool full_messages) -> untyped
|
1456
|
-
|
1457
|
-
# Adds +message+ to the error messages and used validator type to +details+ on +attribute+.
|
1458
|
-
# More than one error can be added to the same +attribute+.
|
1459
|
-
# If no +message+ is supplied, <tt>:invalid</tt> is assumed.
|
1460
|
-
#
|
1461
|
-
# person.errors.add(:name)
|
1462
|
-
# # => ["is invalid"]
|
1463
|
-
# person.errors.add(:name, :not_implemented, message: "must be implemented")
|
1464
|
-
# # => ["is invalid", "must be implemented"]
|
1465
|
-
#
|
1466
|
-
# person.errors.messages
|
1467
|
-
# # => {:name=>["is invalid", "must be implemented"]}
|
1468
|
-
#
|
1469
|
-
# person.errors.details
|
1470
|
-
# # => {:name=>[{error: :not_implemented}, {error: :invalid}]}
|
1471
|
-
#
|
1472
|
-
# If +message+ is a symbol, it will be translated using the appropriate
|
1473
|
-
# scope (see +generate_message+).
|
1474
|
-
#
|
1475
|
-
# If +message+ is a proc, it will be called, allowing for things like
|
1476
|
-
# <tt>Time.now</tt> to be used within an error.
|
1477
|
-
#
|
1478
|
-
# If the <tt>:strict</tt> option is set to +true+, it will raise
|
1479
|
-
# ActiveModel::StrictValidationFailed instead of adding the error.
|
1480
|
-
# <tt>:strict</tt> option can also be set to any other exception.
|
1481
|
-
#
|
1482
|
-
# person.errors.add(:name, :invalid, strict: true)
|
1483
|
-
# # => ActiveModel::StrictValidationFailed: Name is invalid
|
1484
|
-
# person.errors.add(:name, :invalid, strict: NameIsInvalid)
|
1485
|
-
# # => NameIsInvalid: Name is invalid
|
1486
|
-
#
|
1487
|
-
# person.errors.messages # => {}
|
1488
|
-
#
|
1489
|
-
# +attribute+ should be set to <tt>:base</tt> if the error is not
|
1490
|
-
# directly associated with a single attribute.
|
1491
|
-
#
|
1492
|
-
# person.errors.add(:base, :name_or_email_blank,
|
1493
|
-
# message: "either name or email must be present")
|
1494
|
-
# person.errors.messages
|
1495
|
-
# # => {:base=>["either name or email must be present"]}
|
1496
|
-
# person.errors.details
|
1497
|
-
# # => {:base=>[{error: :name_or_email_blank}]}
|
1498
|
-
def add: (untyped attribute, ?::Symbol message, ?::Hash[untyped, untyped] options) -> untyped
|
1499
|
-
|
1500
|
-
# Returns +true+ if an error on the attribute with the given message is
|
1501
|
-
# present, or +false+ otherwise. +message+ is treated the same as for +add+.
|
1502
|
-
#
|
1503
|
-
# person.errors.add :name, :blank
|
1504
|
-
# person.errors.added? :name, :blank # => true
|
1505
|
-
# person.errors.added? :name, "can't be blank" # => true
|
1506
|
-
#
|
1507
|
-
# If the error message requires options, then it returns +true+ with
|
1508
|
-
# the correct options, or +false+ with incorrect or missing options.
|
1509
|
-
#
|
1510
|
-
# person.errors.add :name, :too_long, { count: 25 }
|
1511
|
-
# person.errors.added? :name, :too_long, count: 25 # => true
|
1512
|
-
# person.errors.added? :name, "is too long (maximum is 25 characters)" # => true
|
1513
|
-
# person.errors.added? :name, :too_long, count: 24 # => false
|
1514
|
-
# person.errors.added? :name, :too_long # => false
|
1515
|
-
# person.errors.added? :name, "is too long" # => false
|
1516
|
-
def added?: (untyped attribute, ?::Symbol message, ?::Hash[untyped, untyped] options) -> untyped
|
1517
|
-
|
1518
|
-
# Returns +true+ if an error on the attribute with the given message is
|
1519
|
-
# present, or +false+ otherwise. +message+ is treated the same as for +add+.
|
1520
|
-
#
|
1521
|
-
# person.errors.add :age
|
1522
|
-
# person.errors.add :name, :too_long, { count: 25 }
|
1523
|
-
# person.errors.of_kind? :age # => true
|
1524
|
-
# person.errors.of_kind? :name # => false
|
1525
|
-
# person.errors.of_kind? :name, :too_long # => true
|
1526
|
-
# person.errors.of_kind? :name, "is too long (maximum is 25 characters)" # => true
|
1527
|
-
# person.errors.of_kind? :name, :not_too_long # => false
|
1528
|
-
# person.errors.of_kind? :name, "is too long" # => false
|
1529
|
-
def of_kind?: (untyped attribute, ?::Symbol message) -> untyped
|
1530
|
-
|
1531
|
-
# Returns all the full error messages in an array.
|
1532
|
-
#
|
1533
|
-
# class Person
|
1534
|
-
# validates_presence_of :name, :address, :email
|
1535
|
-
# validates_length_of :name, in: 5..30
|
1536
|
-
# end
|
1537
|
-
#
|
1538
|
-
# person = Person.create(address: '123 First St.')
|
1539
|
-
# person.errors.full_messages
|
1540
|
-
# # => ["Name is too short (minimum is 5 characters)", "Name can't be blank", "Email can't be blank"]
|
1541
|
-
def full_messages: () -> untyped
|
1542
|
-
|
1543
|
-
alias to_a full_messages
|
1544
|
-
|
1545
|
-
# Returns all the full error messages for a given attribute in an array.
|
1546
|
-
#
|
1547
|
-
# class Person
|
1548
|
-
# validates_presence_of :name, :email
|
1549
|
-
# validates_length_of :name, in: 5..30
|
1550
|
-
# end
|
1551
|
-
#
|
1552
|
-
# person = Person.create()
|
1553
|
-
# person.errors.full_messages_for(:name)
|
1554
|
-
# # => ["Name is too short (minimum is 5 characters)", "Name can't be blank"]
|
1555
|
-
def full_messages_for: (untyped attribute) -> untyped
|
1556
|
-
|
1557
|
-
# Returns a full message for a given attribute.
|
1558
|
-
#
|
1559
|
-
# person.errors.full_message(:name, 'is invalid') # => "Name is invalid"
|
1560
|
-
#
|
1561
|
-
# The `"%{attribute} %{message}"` error format can be overridden with either
|
1562
|
-
#
|
1563
|
-
# * <tt>activemodel.errors.models.person/contacts/addresses.attributes.street.format</tt>
|
1564
|
-
# * <tt>activemodel.errors.models.person/contacts/addresses.format</tt>
|
1565
|
-
# * <tt>activemodel.errors.models.person.attributes.name.format</tt>
|
1566
|
-
# * <tt>activemodel.errors.models.person.format</tt>
|
1567
|
-
# * <tt>errors.format</tt>
|
1568
|
-
def full_message: (untyped attribute, untyped message) -> untyped
|
1569
|
-
|
1570
|
-
# Translates an error message in its default scope
|
1571
|
-
# (<tt>activemodel.errors.messages</tt>).
|
1572
|
-
#
|
1573
|
-
# Error messages are first looked up in <tt>activemodel.errors.models.MODEL.attributes.ATTRIBUTE.MESSAGE</tt>,
|
1574
|
-
# if it's not there, it's looked up in <tt>activemodel.errors.models.MODEL.MESSAGE</tt> and if
|
1575
|
-
# that is not there also, it returns the translation of the default message
|
1576
|
-
# (e.g. <tt>activemodel.errors.messages.MESSAGE</tt>). The translated model
|
1577
|
-
# name, translated attribute name and the value are available for
|
1578
|
-
# interpolation.
|
1579
|
-
#
|
1580
|
-
# When using inheritance in your models, it will check all the inherited
|
1581
|
-
# models too, but only if the model itself hasn't been found. Say you have
|
1582
|
-
# <tt>class Admin < User; end</tt> and you wanted the translation for
|
1583
|
-
# the <tt>:blank</tt> error message for the <tt>title</tt> attribute,
|
1584
|
-
# it looks for these translations:
|
1585
|
-
#
|
1586
|
-
# * <tt>activemodel.errors.models.admin.attributes.title.blank</tt>
|
1587
|
-
# * <tt>activemodel.errors.models.admin.blank</tt>
|
1588
|
-
# * <tt>activemodel.errors.models.user.attributes.title.blank</tt>
|
1589
|
-
# * <tt>activemodel.errors.models.user.blank</tt>
|
1590
|
-
# * any default you provided through the +options+ hash (in the <tt>activemodel.errors</tt> scope)
|
1591
|
-
# * <tt>activemodel.errors.messages.blank</tt>
|
1592
|
-
# * <tt>errors.attributes.title.blank</tt>
|
1593
|
-
# * <tt>errors.messages.blank</tt>
|
1594
|
-
def generate_message: (untyped attribute, ?::Symbol `type`, ?::Hash[untyped, untyped] options) -> untyped
|
1595
|
-
|
1596
|
-
def marshal_dump: () -> ::Array[untyped]
|
1597
|
-
|
1598
|
-
def marshal_load: (untyped array) -> untyped
|
1599
|
-
|
1600
|
-
def init_with: (untyped coder) -> untyped
|
1601
|
-
|
1602
|
-
def normalize_message: (untyped attribute, untyped message, untyped options) -> untyped
|
1603
|
-
|
1604
|
-
def normalize_detail: (untyped message, untyped options) -> untyped
|
1605
|
-
|
1606
|
-
def without_default_proc: (untyped hash) -> untyped
|
1607
|
-
|
1608
|
-
def apply_default_array: (untyped hash) -> untyped
|
1609
|
-
end
|
1610
|
-
|
1611
|
-
# Raised when a validation cannot be corrected by end users and are considered
|
1612
|
-
# exceptional.
|
1613
|
-
#
|
1614
|
-
# class Person
|
1615
|
-
# include ActiveModel::Validations
|
1616
|
-
#
|
1617
|
-
# attr_accessor :name
|
1618
|
-
#
|
1619
|
-
# validates_presence_of :name, strict: true
|
1620
|
-
# end
|
1621
|
-
#
|
1622
|
-
# person = Person.new
|
1623
|
-
# person.name = nil
|
1624
|
-
# person.valid?
|
1625
|
-
# # => ActiveModel::StrictValidationFailed: Name can't be blank
|
1626
|
-
class StrictValidationFailed < StandardError
|
1627
|
-
end
|
1628
|
-
|
1629
|
-
# Raised when attribute values are out of range.
|
1630
|
-
class RangeError < ::RangeError
|
1631
|
-
end
|
1632
|
-
|
1633
|
-
# Raised when unknown attributes are supplied via mass assignment.
|
1634
|
-
#
|
1635
|
-
# class Person
|
1636
|
-
# include ActiveModel::AttributeAssignment
|
1637
|
-
# include ActiveModel::Validations
|
1638
|
-
# end
|
1639
|
-
#
|
1640
|
-
# person = Person.new
|
1641
|
-
# person.assign_attributes(name: 'Gorby')
|
1642
|
-
# # => ActiveModel::UnknownAttributeError: unknown attribute 'name' for Person.
|
1643
|
-
class UnknownAttributeError[T] < NoMethodError[T]
|
1644
|
-
attr_reader record: untyped
|
1645
|
-
|
1646
|
-
attr_reader attribute: untyped
|
1647
|
-
|
1648
|
-
def initialize: (untyped record, untyped attribute) -> untyped
|
1649
|
-
end
|
1650
|
-
end
|
1651
|
-
|
1652
|
-
module ActiveModel
|
1653
|
-
# Raised when forbidden attributes are used for mass assignment.
|
1654
|
-
#
|
1655
|
-
# class Person < ActiveRecord::Base
|
1656
|
-
# end
|
1657
|
-
#
|
1658
|
-
# params = ActionController::Parameters.new(name: 'Bob')
|
1659
|
-
# Person.new(params)
|
1660
|
-
# # => ActiveModel::ForbiddenAttributesError
|
1661
|
-
#
|
1662
|
-
# params.permit!
|
1663
|
-
# Person.new(params)
|
1664
|
-
# # => #<Person id: nil, name: "Bob">
|
1665
|
-
class ForbiddenAttributesError < StandardError
|
1666
|
-
end
|
1667
|
-
|
1668
|
-
module ForbiddenAttributesProtection
|
1669
|
-
def sanitize_for_mass_assignment: (untyped attributes) -> untyped
|
1670
|
-
|
1671
|
-
alias sanitize_forbidden_attributes sanitize_for_mass_assignment
|
1672
|
-
end
|
1673
|
-
end
|
1674
|
-
|
1675
|
-
module ActiveModel
|
1676
|
-
# Returns the version of the currently loaded \Active \Model as a <tt>Gem::Version</tt>
|
1677
|
-
def self.gem_version: () -> Gem::Version
|
1678
|
-
|
1679
|
-
module VERSION
|
1680
|
-
MAJOR: ::Integer
|
1681
|
-
|
1682
|
-
MINOR: ::Integer
|
1683
|
-
|
1684
|
-
TINY: ::Integer
|
1685
|
-
|
1686
|
-
PRE: ::String
|
1687
|
-
|
1688
|
-
STRING: untyped
|
1689
|
-
end
|
1690
|
-
end
|
1691
|
-
|
1692
|
-
module ActiveModel
|
1693
|
-
module Lint
|
1694
|
-
# == Active \Model \Lint \Tests
|
1695
|
-
#
|
1696
|
-
# You can test whether an object is compliant with the Active \Model API by
|
1697
|
-
# including <tt>ActiveModel::Lint::Tests</tt> in your TestCase. It will
|
1698
|
-
# include tests that tell you whether your object is fully compliant,
|
1699
|
-
# or if not, which aspects of the API are not implemented.
|
1700
|
-
#
|
1701
|
-
# Note an object is not required to implement all APIs in order to work
|
1702
|
-
# with Action Pack. This module only intends to provide guidance in case
|
1703
|
-
# you want all features out of the box.
|
1704
|
-
#
|
1705
|
-
# These tests do not attempt to determine the semantic correctness of the
|
1706
|
-
# returned values. For instance, you could implement <tt>valid?</tt> to
|
1707
|
-
# always return +true+, and the tests would pass. It is up to you to ensure
|
1708
|
-
# that the values are semantically meaningful.
|
1709
|
-
#
|
1710
|
-
# Objects you pass in are expected to return a compliant object from a call
|
1711
|
-
# to <tt>to_model</tt>. It is perfectly fine for <tt>to_model</tt> to return
|
1712
|
-
# +self+.
|
1713
|
-
module Tests
|
1714
|
-
# Passes if the object's model responds to <tt>to_key</tt> and if calling
|
1715
|
-
# this method returns +nil+ when the object is not persisted.
|
1716
|
-
# Fails otherwise.
|
1717
|
-
#
|
1718
|
-
# <tt>to_key</tt> returns an Enumerable of all (primary) key attributes
|
1719
|
-
# of the model, and is used to a generate unique DOM id for the object.
|
1720
|
-
def test_to_key: () -> untyped
|
1721
|
-
|
1722
|
-
# Passes if the object's model responds to <tt>to_param</tt> and if
|
1723
|
-
# calling this method returns +nil+ when the object is not persisted.
|
1724
|
-
# Fails otherwise.
|
1725
|
-
#
|
1726
|
-
# <tt>to_param</tt> is used to represent the object's key in URLs.
|
1727
|
-
# Implementers can decide to either raise an exception or provide a
|
1728
|
-
# default in case the record uses a composite primary key. There are no
|
1729
|
-
# tests for this behavior in lint because it doesn't make sense to force
|
1730
|
-
# any of the possible implementation strategies on the implementer.
|
1731
|
-
def test_to_param: () -> untyped
|
1732
|
-
|
1733
|
-
# Passes if the object's model responds to <tt>to_partial_path</tt> and if
|
1734
|
-
# calling this method returns a string. Fails otherwise.
|
1735
|
-
#
|
1736
|
-
# <tt>to_partial_path</tt> is used for looking up partials. For example,
|
1737
|
-
# a BlogPost model might return "blog_posts/blog_post".
|
1738
|
-
def test_to_partial_path: () -> untyped
|
1739
|
-
|
1740
|
-
# Passes if the object's model responds to <tt>persisted?</tt> and if
|
1741
|
-
# calling this method returns either +true+ or +false+. Fails otherwise.
|
1742
|
-
#
|
1743
|
-
# <tt>persisted?</tt> is used when calculating the URL for an object.
|
1744
|
-
# If the object is not persisted, a form for that object, for instance,
|
1745
|
-
# will route to the create action. If it is persisted, a form for the
|
1746
|
-
# object will route to the update action.
|
1747
|
-
def test_persisted?: () -> untyped
|
1748
|
-
|
1749
|
-
# Passes if the object's model responds to <tt>model_name</tt> both as
|
1750
|
-
# an instance method and as a class method, and if calling this method
|
1751
|
-
# returns a string with some convenience methods: <tt>:human</tt>,
|
1752
|
-
# <tt>:singular</tt> and <tt>:plural</tt>.
|
1753
|
-
#
|
1754
|
-
# Check ActiveModel::Naming for more information.
|
1755
|
-
def test_model_naming: () -> untyped
|
1756
|
-
|
1757
|
-
# Passes if the object's model responds to <tt>errors</tt> and if calling
|
1758
|
-
# <tt>[](attribute)</tt> on the result of this method returns an array.
|
1759
|
-
# Fails otherwise.
|
1760
|
-
#
|
1761
|
-
# <tt>errors[attribute]</tt> is used to retrieve the errors of a model
|
1762
|
-
# for a given attribute. If errors are present, the method should return
|
1763
|
-
# an array of strings that are the errors for the attribute in question.
|
1764
|
-
# If localization is used, the strings should be localized for the current
|
1765
|
-
# locale. If no error is present, the method should return an empty array.
|
1766
|
-
def test_errors_aref: () -> untyped
|
1767
|
-
|
1768
|
-
def model: () -> untyped
|
1769
|
-
|
1770
|
-
def assert_boolean: (untyped result, untyped name) -> untyped
|
1771
|
-
end
|
1772
|
-
end
|
1773
|
-
end
|
1774
|
-
|
1775
|
-
module ActiveModel
|
1776
|
-
# == Active \Model \Basic \Model
|
1777
|
-
#
|
1778
|
-
# Includes the required interface for an object to interact with
|
1779
|
-
# Action Pack and Action View, using different Active Model modules.
|
1780
|
-
# It includes model name introspections, conversions, translations and
|
1781
|
-
# validations. Besides that, it allows you to initialize the object with a
|
1782
|
-
# hash of attributes, pretty much like Active Record does.
|
1783
|
-
#
|
1784
|
-
# A minimal implementation could be:
|
1785
|
-
#
|
1786
|
-
# class Person
|
1787
|
-
# include ActiveModel::Model
|
1788
|
-
# attr_accessor :name, :age
|
1789
|
-
# end
|
1790
|
-
#
|
1791
|
-
# person = Person.new(name: 'bob', age: '18')
|
1792
|
-
# person.name # => "bob"
|
1793
|
-
# person.age # => "18"
|
1794
|
-
#
|
1795
|
-
# Note that, by default, <tt>ActiveModel::Model</tt> implements <tt>persisted?</tt>
|
1796
|
-
# to return +false+, which is the most common case. You may want to override
|
1797
|
-
# it in your class to simulate a different scenario:
|
1798
|
-
#
|
1799
|
-
# class Person
|
1800
|
-
# include ActiveModel::Model
|
1801
|
-
# attr_accessor :id, :name
|
1802
|
-
#
|
1803
|
-
# def persisted?
|
1804
|
-
# self.id == 1
|
1805
|
-
# end
|
1806
|
-
# end
|
1807
|
-
#
|
1808
|
-
# person = Person.new(id: 1, name: 'bob')
|
1809
|
-
# person.persisted? # => true
|
1810
|
-
#
|
1811
|
-
# Also, if for some reason you need to run code on <tt>initialize</tt>, make
|
1812
|
-
# sure you call +super+ if you want the attributes hash initialization to
|
1813
|
-
# happen.
|
1814
|
-
#
|
1815
|
-
# class Person
|
1816
|
-
# include ActiveModel::Model
|
1817
|
-
# attr_accessor :id, :name, :omg
|
1818
|
-
#
|
1819
|
-
# def initialize(attributes={})
|
1820
|
-
# super
|
1821
|
-
# @omg ||= true
|
1822
|
-
# end
|
1823
|
-
# end
|
1824
|
-
#
|
1825
|
-
# person = Person.new(id: 1, name: 'bob')
|
1826
|
-
# person.omg # => true
|
1827
|
-
#
|
1828
|
-
# For more detailed information on other functionalities available, please
|
1829
|
-
# refer to the specific modules included in <tt>ActiveModel::Model</tt>
|
1830
|
-
# (see below).
|
1831
|
-
module Model
|
1832
|
-
extend ActiveSupport::Concern
|
1833
|
-
|
1834
|
-
include ActiveModel::AttributeAssignment
|
1835
|
-
|
1836
|
-
include ActiveModel::Validations
|
1837
|
-
|
1838
|
-
extend ::ActiveModel::Validations::ClassMethods
|
1839
|
-
|
1840
|
-
include ActiveModel::Conversion
|
1841
|
-
|
1842
|
-
extend ::ActiveModel::Conversion::ClassMethods
|
1843
|
-
|
1844
|
-
extend ActiveModel::Naming
|
1845
|
-
|
1846
|
-
extend ActiveModel::Translation
|
1847
|
-
|
1848
|
-
# Initializes a new model with the given +params+.
|
1849
|
-
#
|
1850
|
-
# class Person
|
1851
|
-
# include ActiveModel::Model
|
1852
|
-
# attr_accessor :name, :age
|
1853
|
-
# end
|
1854
|
-
#
|
1855
|
-
# person = Person.new(name: 'bob', age: '18')
|
1856
|
-
# person.name # => "bob"
|
1857
|
-
# person.age # => "18"
|
1858
|
-
def initialize: (?::Hash[untyped, untyped] attributes) -> untyped
|
1859
|
-
|
1860
|
-
# Indicates if the model is persisted. Default is +false+.
|
1861
|
-
#
|
1862
|
-
# class Person
|
1863
|
-
# include ActiveModel::Model
|
1864
|
-
# attr_accessor :id, :name
|
1865
|
-
# end
|
1866
|
-
#
|
1867
|
-
# person = Person.new(id: 1, name: 'bob')
|
1868
|
-
# person.persisted? # => false
|
1869
|
-
def persisted?: () -> ::FalseClass
|
1870
|
-
end
|
1871
|
-
end
|
1872
|
-
|
1873
|
-
module ActiveModel
|
1874
|
-
class Name
|
1875
|
-
include Comparable
|
1876
|
-
|
1877
|
-
attr_reader singular: untyped
|
1878
|
-
|
1879
|
-
attr_reader plural: untyped
|
1880
|
-
|
1881
|
-
attr_reader element: untyped
|
1882
|
-
|
1883
|
-
attr_reader collection: untyped
|
1884
|
-
|
1885
|
-
attr_reader singular_route_key: untyped
|
1886
|
-
|
1887
|
-
attr_reader route_key: untyped
|
1888
|
-
|
1889
|
-
attr_reader param_key: untyped
|
1890
|
-
|
1891
|
-
attr_reader i18n_key: untyped
|
1892
|
-
|
1893
|
-
attr_reader name: untyped
|
1894
|
-
|
1895
|
-
alias cache_key collection
|
1896
|
-
|
1897
|
-
# Returns a new ActiveModel::Name instance. By default, the +namespace+
|
1898
|
-
# and +name+ option will take the namespace and name of the given class
|
1899
|
-
# respectively.
|
1900
|
-
#
|
1901
|
-
# module Foo
|
1902
|
-
# class Bar
|
1903
|
-
# end
|
1904
|
-
# end
|
1905
|
-
#
|
1906
|
-
# ActiveModel::Name.new(Foo::Bar).to_s
|
1907
|
-
# # => "Foo::Bar"
|
1908
|
-
def initialize: (untyped klass, ?untyped? namespace, ?untyped? name) -> untyped
|
1909
|
-
|
1910
|
-
# Transform the model name into a more human format, using I18n. By default,
|
1911
|
-
# it will underscore then humanize the class name.
|
1912
|
-
#
|
1913
|
-
# class BlogPost
|
1914
|
-
# extend ActiveModel::Naming
|
1915
|
-
# end
|
1916
|
-
#
|
1917
|
-
# BlogPost.model_name.human # => "Blog post"
|
1918
|
-
#
|
1919
|
-
# Specify +options+ with additional translating options.
|
1920
|
-
def human: (?::Hash[untyped, untyped] options) -> untyped
|
1921
|
-
|
1922
|
-
def _singularize: (untyped string) -> untyped
|
1923
|
-
end
|
1924
|
-
|
1925
|
-
# == Active \Model \Naming
|
1926
|
-
#
|
1927
|
-
# Creates a +model_name+ method on your object.
|
1928
|
-
#
|
1929
|
-
# To implement, just extend ActiveModel::Naming in your object:
|
1930
|
-
#
|
1931
|
-
# class BookCover
|
1932
|
-
# extend ActiveModel::Naming
|
1933
|
-
# end
|
1934
|
-
#
|
1935
|
-
# BookCover.model_name.name # => "BookCover"
|
1936
|
-
# BookCover.model_name.human # => "Book cover"
|
1937
|
-
#
|
1938
|
-
# BookCover.model_name.i18n_key # => :book_cover
|
1939
|
-
# BookModule::BookCover.model_name.i18n_key # => :"book_module/book_cover"
|
1940
|
-
#
|
1941
|
-
# Providing the functionality that ActiveModel::Naming provides in your object
|
1942
|
-
# is required to pass the \Active \Model Lint test. So either extending the
|
1943
|
-
# provided method below, or rolling your own is required.
|
1944
|
-
module Naming
|
1945
|
-
def self.extended: (untyped base) -> untyped
|
1946
|
-
|
1947
|
-
# Returns an ActiveModel::Name object for module. It can be
|
1948
|
-
# used to retrieve all kinds of naming-related information
|
1949
|
-
# (See ActiveModel::Name for more information).
|
1950
|
-
#
|
1951
|
-
# class Person
|
1952
|
-
# extend ActiveModel::Naming
|
1953
|
-
# end
|
1954
|
-
#
|
1955
|
-
# Person.model_name.name # => "Person"
|
1956
|
-
# Person.model_name.class # => ActiveModel::Name
|
1957
|
-
# Person.model_name.singular # => "person"
|
1958
|
-
# Person.model_name.plural # => "people"
|
1959
|
-
def model_name: () -> untyped
|
1960
|
-
|
1961
|
-
# Returns the plural class name of a record or class.
|
1962
|
-
#
|
1963
|
-
# ActiveModel::Naming.plural(post) # => "posts"
|
1964
|
-
# ActiveModel::Naming.plural(Highrise::Person) # => "highrise_people"
|
1965
|
-
def self.plural: (untyped record_or_class) -> untyped
|
1966
|
-
|
1967
|
-
# Returns the singular class name of a record or class.
|
1968
|
-
#
|
1969
|
-
# ActiveModel::Naming.singular(post) # => "post"
|
1970
|
-
# ActiveModel::Naming.singular(Highrise::Person) # => "highrise_person"
|
1971
|
-
def self.singular: (untyped record_or_class) -> untyped
|
1972
|
-
|
1973
|
-
# Identifies whether the class name of a record or class is uncountable.
|
1974
|
-
#
|
1975
|
-
# ActiveModel::Naming.uncountable?(Sheep) # => true
|
1976
|
-
# ActiveModel::Naming.uncountable?(Post) # => false
|
1977
|
-
def self.uncountable?: (untyped record_or_class) -> untyped
|
1978
|
-
|
1979
|
-
# Returns string to use while generating route names. It differs for
|
1980
|
-
# namespaced models regarding whether it's inside isolated engine.
|
1981
|
-
#
|
1982
|
-
# # For isolated engine:
|
1983
|
-
# ActiveModel::Naming.singular_route_key(Blog::Post) # => "post"
|
1984
|
-
#
|
1985
|
-
# # For shared engine:
|
1986
|
-
# ActiveModel::Naming.singular_route_key(Blog::Post) # => "blog_post"
|
1987
|
-
def self.singular_route_key: (untyped record_or_class) -> untyped
|
1988
|
-
|
1989
|
-
# Returns string to use while generating route names. It differs for
|
1990
|
-
# namespaced models regarding whether it's inside isolated engine.
|
1991
|
-
#
|
1992
|
-
# # For isolated engine:
|
1993
|
-
# ActiveModel::Naming.route_key(Blog::Post) # => "posts"
|
1994
|
-
#
|
1995
|
-
# # For shared engine:
|
1996
|
-
# ActiveModel::Naming.route_key(Blog::Post) # => "blog_posts"
|
1997
|
-
#
|
1998
|
-
# The route key also considers if the noun is uncountable and, in
|
1999
|
-
# such cases, automatically appends _index.
|
2000
|
-
def self.route_key: (untyped record_or_class) -> untyped
|
2001
|
-
|
2002
|
-
# Returns string to use for params names. It differs for
|
2003
|
-
# namespaced models regarding whether it's inside isolated engine.
|
2004
|
-
#
|
2005
|
-
# # For isolated engine:
|
2006
|
-
# ActiveModel::Naming.param_key(Blog::Post) # => "post"
|
2007
|
-
#
|
2008
|
-
# # For shared engine:
|
2009
|
-
# ActiveModel::Naming.param_key(Blog::Post) # => "blog_post"
|
2010
|
-
def self.param_key: (untyped record_or_class) -> untyped
|
2011
|
-
|
2012
|
-
def self.model_name_from_record_or_class: (untyped record_or_class) -> untyped
|
2013
|
-
end
|
2014
|
-
end
|
2015
|
-
|
2016
|
-
module ActiveModel
|
2017
|
-
class Railtie < Rails::Railtie
|
2018
|
-
end
|
2019
|
-
end
|
2020
|
-
|
2021
|
-
module ActiveModel
|
2022
|
-
module SecurePassword
|
2023
|
-
extend ActiveSupport::Concern
|
2024
|
-
|
2025
|
-
# BCrypt hash function can handle maximum 72 bytes, and if we pass
|
2026
|
-
# password of length more than 72 bytes it ignores extra characters.
|
2027
|
-
# Hence need to put a restriction on password length.
|
2028
|
-
MAX_PASSWORD_LENGTH_ALLOWED: ::Integer
|
2029
|
-
|
2030
|
-
attr_accessor min_cost: untyped
|
2031
|
-
|
2032
|
-
module ClassMethods
|
2033
|
-
# Adds methods to set and authenticate against a BCrypt password.
|
2034
|
-
# This mechanism requires you to have a +XXX_digest+ attribute.
|
2035
|
-
# Where +XXX+ is the attribute name of your desired password.
|
2036
|
-
#
|
2037
|
-
# The following validations are added automatically:
|
2038
|
-
# * Password must be present on creation
|
2039
|
-
# * Password length should be less than or equal to 72 bytes
|
2040
|
-
# * Confirmation of password (using a +XXX_confirmation+ attribute)
|
2041
|
-
#
|
2042
|
-
# If confirmation validation is not needed, simply leave out the
|
2043
|
-
# value for +XXX_confirmation+ (i.e. don't provide a form field for
|
2044
|
-
# it). When this attribute has a +nil+ value, the validation will not be
|
2045
|
-
# triggered.
|
2046
|
-
#
|
2047
|
-
# For further customizability, it is possible to suppress the default
|
2048
|
-
# validations by passing <tt>validations: false</tt> as an argument.
|
2049
|
-
#
|
2050
|
-
# Add bcrypt (~> 3.1.7) to Gemfile to use #has_secure_password:
|
2051
|
-
#
|
2052
|
-
# gem 'bcrypt', '~> 3.1.7'
|
2053
|
-
#
|
2054
|
-
# Example using Active Record (which automatically includes ActiveModel::SecurePassword):
|
2055
|
-
#
|
2056
|
-
# # Schema: User(name:string, password_digest:string, recovery_password_digest:string)
|
2057
|
-
# class User < ActiveRecord::Base
|
2058
|
-
# has_secure_password
|
2059
|
-
# has_secure_password :recovery_password, validations: false
|
2060
|
-
# end
|
2061
|
-
#
|
2062
|
-
# user = User.new(name: 'david', password: '', password_confirmation: 'nomatch')
|
2063
|
-
# user.save # => false, password required
|
2064
|
-
# user.password = 'mUc3m00RsqyRe'
|
2065
|
-
# user.save # => false, confirmation doesn't match
|
2066
|
-
# user.password_confirmation = 'mUc3m00RsqyRe'
|
2067
|
-
# user.save # => true
|
2068
|
-
# user.recovery_password = "42password"
|
2069
|
-
# user.recovery_password_digest # => "$2a$04$iOfhwahFymCs5weB3BNH/uXkTG65HR.qpW.bNhEjFP3ftli3o5DQC"
|
2070
|
-
# user.save # => true
|
2071
|
-
# user.authenticate('notright') # => false
|
2072
|
-
# user.authenticate('mUc3m00RsqyRe') # => user
|
2073
|
-
# user.authenticate_recovery_password('42password') # => user
|
2074
|
-
# User.find_by(name: 'david').try(:authenticate, 'notright') # => false
|
2075
|
-
# User.find_by(name: 'david').try(:authenticate, 'mUc3m00RsqyRe') # => user
|
2076
|
-
def has_secure_password: (?::Symbol attribute, ?validations: bool validations) -> untyped
|
2077
|
-
end
|
2078
|
-
|
2079
|
-
class InstanceMethodsOnActivation < Module
|
2080
|
-
def initialize: (untyped attribute) -> untyped
|
2081
|
-
end
|
2082
|
-
end
|
2083
|
-
end
|
2084
|
-
|
2085
|
-
module ActiveModel
|
2086
|
-
# == Active \Model \Serialization
|
2087
|
-
#
|
2088
|
-
# Provides a basic serialization to a serializable_hash for your objects.
|
2089
|
-
#
|
2090
|
-
# A minimal implementation could be:
|
2091
|
-
#
|
2092
|
-
# class Person
|
2093
|
-
# include ActiveModel::Serialization
|
2094
|
-
#
|
2095
|
-
# attr_accessor :name
|
2096
|
-
#
|
2097
|
-
# def attributes
|
2098
|
-
# {'name' => nil}
|
2099
|
-
# end
|
2100
|
-
# end
|
2101
|
-
#
|
2102
|
-
# Which would provide you with:
|
2103
|
-
#
|
2104
|
-
# person = Person.new
|
2105
|
-
# person.serializable_hash # => {"name"=>nil}
|
2106
|
-
# person.name = "Bob"
|
2107
|
-
# person.serializable_hash # => {"name"=>"Bob"}
|
2108
|
-
#
|
2109
|
-
# An +attributes+ hash must be defined and should contain any attributes you
|
2110
|
-
# need to be serialized. Attributes must be strings, not symbols.
|
2111
|
-
# When called, serializable hash will use instance methods that match the name
|
2112
|
-
# of the attributes hash's keys. In order to override this behavior, take a look
|
2113
|
-
# at the private method +read_attribute_for_serialization+.
|
2114
|
-
#
|
2115
|
-
# ActiveModel::Serializers::JSON module automatically includes
|
2116
|
-
# the <tt>ActiveModel::Serialization</tt> module, so there is no need to
|
2117
|
-
# explicitly include <tt>ActiveModel::Serialization</tt>.
|
2118
|
-
#
|
2119
|
-
# A minimal implementation including JSON would be:
|
2120
|
-
#
|
2121
|
-
# class Person
|
2122
|
-
# include ActiveModel::Serializers::JSON
|
2123
|
-
#
|
2124
|
-
# attr_accessor :name
|
2125
|
-
#
|
2126
|
-
# def attributes
|
2127
|
-
# {'name' => nil}
|
2128
|
-
# end
|
2129
|
-
# end
|
2130
|
-
#
|
2131
|
-
# Which would provide you with:
|
2132
|
-
#
|
2133
|
-
# person = Person.new
|
2134
|
-
# person.serializable_hash # => {"name"=>nil}
|
2135
|
-
# person.as_json # => {"name"=>nil}
|
2136
|
-
# person.to_json # => "{\"name\":null}"
|
2137
|
-
#
|
2138
|
-
# person.name = "Bob"
|
2139
|
-
# person.serializable_hash # => {"name"=>"Bob"}
|
2140
|
-
# person.as_json # => {"name"=>"Bob"}
|
2141
|
-
# person.to_json # => "{\"name\":\"Bob\"}"
|
2142
|
-
#
|
2143
|
-
# Valid options are <tt>:only</tt>, <tt>:except</tt>, <tt>:methods</tt> and
|
2144
|
-
# <tt>:include</tt>. The following are all valid examples:
|
2145
|
-
#
|
2146
|
-
# person.serializable_hash(only: 'name')
|
2147
|
-
# person.serializable_hash(include: :address)
|
2148
|
-
# person.serializable_hash(include: { address: { only: 'city' }})
|
2149
|
-
module Serialization
|
2150
|
-
# Returns a serialized hash of your object.
|
2151
|
-
#
|
2152
|
-
# class Person
|
2153
|
-
# include ActiveModel::Serialization
|
2154
|
-
#
|
2155
|
-
# attr_accessor :name, :age
|
2156
|
-
#
|
2157
|
-
# def attributes
|
2158
|
-
# {'name' => nil, 'age' => nil}
|
2159
|
-
# end
|
2160
|
-
#
|
2161
|
-
# def capitalized_name
|
2162
|
-
# name.capitalize
|
2163
|
-
# end
|
2164
|
-
# end
|
2165
|
-
#
|
2166
|
-
# person = Person.new
|
2167
|
-
# person.name = 'bob'
|
2168
|
-
# person.age = 22
|
2169
|
-
# person.serializable_hash # => {"name"=>"bob", "age"=>22}
|
2170
|
-
# person.serializable_hash(only: :name) # => {"name"=>"bob"}
|
2171
|
-
# person.serializable_hash(except: :name) # => {"age"=>22}
|
2172
|
-
# person.serializable_hash(methods: :capitalized_name)
|
2173
|
-
# # => {"name"=>"bob", "age"=>22, "capitalized_name"=>"Bob"}
|
2174
|
-
#
|
2175
|
-
# Example with <tt>:include</tt> option
|
2176
|
-
#
|
2177
|
-
# class User
|
2178
|
-
# include ActiveModel::Serializers::JSON
|
2179
|
-
# attr_accessor :name, :notes # Emulate has_many :notes
|
2180
|
-
# def attributes
|
2181
|
-
# {'name' => nil}
|
2182
|
-
# end
|
2183
|
-
# end
|
2184
|
-
#
|
2185
|
-
# class Note
|
2186
|
-
# include ActiveModel::Serializers::JSON
|
2187
|
-
# attr_accessor :title, :text
|
2188
|
-
# def attributes
|
2189
|
-
# {'title' => nil, 'text' => nil}
|
2190
|
-
# end
|
2191
|
-
# end
|
2192
|
-
#
|
2193
|
-
# note = Note.new
|
2194
|
-
# note.title = 'Battle of Austerlitz'
|
2195
|
-
# note.text = 'Some text here'
|
2196
|
-
#
|
2197
|
-
# user = User.new
|
2198
|
-
# user.name = 'Napoleon'
|
2199
|
-
# user.notes = [note]
|
2200
|
-
#
|
2201
|
-
# user.serializable_hash
|
2202
|
-
# # => {"name" => "Napoleon"}
|
2203
|
-
# user.serializable_hash(include: { notes: { only: 'title' }})
|
2204
|
-
# # => {"name" => "Napoleon", "notes" => [{"title"=>"Battle of Austerlitz"}]}
|
2205
|
-
def serializable_hash: (?untyped? options) -> untyped
|
2206
|
-
|
2207
|
-
# Hook method defining how an attribute value should be retrieved for
|
2208
|
-
# serialization. By default this is assumed to be an instance named after
|
2209
|
-
# the attribute. Override this method in subclasses should you need to
|
2210
|
-
# retrieve the value for a given attribute differently:
|
2211
|
-
#
|
2212
|
-
# class MyClass
|
2213
|
-
# include ActiveModel::Serialization
|
2214
|
-
#
|
2215
|
-
# def initialize(data = {})
|
2216
|
-
# @data = data
|
2217
|
-
# end
|
2218
|
-
#
|
2219
|
-
# def read_attribute_for_serialization(key)
|
2220
|
-
# @data[key]
|
2221
|
-
# end
|
2222
|
-
# end
|
2223
|
-
alias read_attribute_for_serialization send
|
2224
|
-
|
2225
|
-
def serializable_add_includes: (?::Hash[untyped, untyped] options) { (untyped, untyped, untyped) -> untyped } -> (nil | untyped)
|
2226
|
-
end
|
2227
|
-
end
|
2228
|
-
|
2229
|
-
module ActiveModel
|
2230
|
-
module Serializers
|
2231
|
-
# == Active \Model \JSON \Serializer
|
2232
|
-
module JSON
|
2233
|
-
extend ActiveSupport::Concern
|
2234
|
-
|
2235
|
-
include ActiveModel::Serialization
|
2236
|
-
|
2237
|
-
extend ActiveModel::Naming
|
2238
|
-
|
2239
|
-
# Returns a hash representing the model. Some configuration can be
|
2240
|
-
# passed through +options+.
|
2241
|
-
#
|
2242
|
-
# The option <tt>include_root_in_json</tt> controls the top-level behavior
|
2243
|
-
# of +as_json+. If +true+, +as_json+ will emit a single root node named
|
2244
|
-
# after the object's type. The default value for <tt>include_root_in_json</tt>
|
2245
|
-
# option is +false+.
|
2246
|
-
#
|
2247
|
-
# user = User.find(1)
|
2248
|
-
# user.as_json
|
2249
|
-
# # => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
|
2250
|
-
# # "created_at" => "2006-08-01T17:27:133.000Z", "awesome" => true}
|
2251
|
-
#
|
2252
|
-
# ActiveRecord::Base.include_root_in_json = true
|
2253
|
-
#
|
2254
|
-
# user.as_json
|
2255
|
-
# # => { "user" => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
|
2256
|
-
# # "created_at" => "2006-08-01T17:27:13.000Z", "awesome" => true } }
|
2257
|
-
#
|
2258
|
-
# This behavior can also be achieved by setting the <tt>:root</tt> option
|
2259
|
-
# to +true+ as in:
|
2260
|
-
#
|
2261
|
-
# user = User.find(1)
|
2262
|
-
# user.as_json(root: true)
|
2263
|
-
# # => { "user" => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
|
2264
|
-
# # "created_at" => "2006-08-01T17:27:13.000Z", "awesome" => true } }
|
2265
|
-
#
|
2266
|
-
# Without any +options+, the returned Hash will include all the model's
|
2267
|
-
# attributes.
|
2268
|
-
#
|
2269
|
-
# user = User.find(1)
|
2270
|
-
# user.as_json
|
2271
|
-
# # => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
|
2272
|
-
# # "created_at" => "2006-08-01T17:27:13.000Z", "awesome" => true}
|
2273
|
-
#
|
2274
|
-
# The <tt>:only</tt> and <tt>:except</tt> options can be used to limit
|
2275
|
-
# the attributes included, and work similar to the +attributes+ method.
|
2276
|
-
#
|
2277
|
-
# user.as_json(only: [:id, :name])
|
2278
|
-
# # => { "id" => 1, "name" => "Konata Izumi" }
|
2279
|
-
#
|
2280
|
-
# user.as_json(except: [:id, :created_at, :age])
|
2281
|
-
# # => { "name" => "Konata Izumi", "awesome" => true }
|
2282
|
-
#
|
2283
|
-
# To include the result of some method calls on the model use <tt>:methods</tt>:
|
2284
|
-
#
|
2285
|
-
# user.as_json(methods: :permalink)
|
2286
|
-
# # => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
|
2287
|
-
# # "created_at" => "2006-08-01T17:27:13.000Z", "awesome" => true,
|
2288
|
-
# # "permalink" => "1-konata-izumi" }
|
2289
|
-
#
|
2290
|
-
# To include associations use <tt>:include</tt>:
|
2291
|
-
#
|
2292
|
-
# user.as_json(include: :posts)
|
2293
|
-
# # => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
|
2294
|
-
# # "created_at" => "2006-08-01T17:27:13.000Z", "awesome" => true,
|
2295
|
-
# # "posts" => [ { "id" => 1, "author_id" => 1, "title" => "Welcome to the weblog" },
|
2296
|
-
# # { "id" => 2, "author_id" => 1, "title" => "So I was thinking" } ] }
|
2297
|
-
#
|
2298
|
-
# Second level and higher order associations work as well:
|
2299
|
-
#
|
2300
|
-
# user.as_json(include: { posts: {
|
2301
|
-
# include: { comments: {
|
2302
|
-
# only: :body } },
|
2303
|
-
# only: :title } })
|
2304
|
-
# # => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
|
2305
|
-
# # "created_at" => "2006-08-01T17:27:13.000Z", "awesome" => true,
|
2306
|
-
# # "posts" => [ { "comments" => [ { "body" => "1st post!" }, { "body" => "Second!" } ],
|
2307
|
-
# # "title" => "Welcome to the weblog" },
|
2308
|
-
# # { "comments" => [ { "body" => "Don't think too hard" } ],
|
2309
|
-
# # "title" => "So I was thinking" } ] }
|
2310
|
-
def as_json: (?untyped? options) -> untyped
|
2311
|
-
|
2312
|
-
# Sets the model +attributes+ from a JSON string. Returns +self+.
|
2313
|
-
#
|
2314
|
-
# class Person
|
2315
|
-
# include ActiveModel::Serializers::JSON
|
2316
|
-
#
|
2317
|
-
# attr_accessor :name, :age, :awesome
|
2318
|
-
#
|
2319
|
-
# def attributes=(hash)
|
2320
|
-
# hash.each do |key, value|
|
2321
|
-
# send("#{key}=", value)
|
2322
|
-
# end
|
2323
|
-
# end
|
2324
|
-
#
|
2325
|
-
# def attributes
|
2326
|
-
# instance_values
|
2327
|
-
# end
|
2328
|
-
# end
|
2329
|
-
#
|
2330
|
-
# json = { name: 'bob', age: 22, awesome:true }.to_json
|
2331
|
-
# person = Person.new
|
2332
|
-
# person.from_json(json) # => #<Person:0x007fec5e7a0088 @age=22, @awesome=true, @name="bob">
|
2333
|
-
# person.name # => "bob"
|
2334
|
-
# person.age # => 22
|
2335
|
-
# person.awesome # => true
|
2336
|
-
#
|
2337
|
-
# The default value for +include_root+ is +false+. You can change it to
|
2338
|
-
# +true+ if the given JSON string includes a single root node.
|
2339
|
-
#
|
2340
|
-
# json = { person: { name: 'bob', age: 22, awesome:true } }.to_json
|
2341
|
-
# person = Person.new
|
2342
|
-
# person.from_json(json, true) # => #<Person:0x007fec5e7a0088 @age=22, @awesome=true, @name="bob">
|
2343
|
-
# person.name # => "bob"
|
2344
|
-
# person.age # => 22
|
2345
|
-
# person.awesome # => true
|
2346
|
-
def from_json: (untyped json, ?untyped include_root) -> untyped
|
2347
|
-
end
|
2348
|
-
end
|
2349
|
-
end
|
2350
|
-
|
2351
|
-
module ActiveModel
|
2352
|
-
# == Active \Model \Translation
|
2353
|
-
#
|
2354
|
-
# Provides integration between your object and the Rails internationalization
|
2355
|
-
# (i18n) framework.
|
2356
|
-
#
|
2357
|
-
# A minimal implementation could be:
|
2358
|
-
#
|
2359
|
-
# class TranslatedPerson
|
2360
|
-
# extend ActiveModel::Translation
|
2361
|
-
# end
|
2362
|
-
#
|
2363
|
-
# TranslatedPerson.human_attribute_name('my_attribute')
|
2364
|
-
# # => "My attribute"
|
2365
|
-
#
|
2366
|
-
# This also provides the required class methods for hooking into the
|
2367
|
-
# Rails internationalization API, including being able to define a
|
2368
|
-
# class based +i18n_scope+ and +lookup_ancestors+ to find translations in
|
2369
|
-
# parent classes.
|
2370
|
-
module Translation
|
2371
|
-
include ActiveModel::Naming
|
2372
|
-
|
2373
|
-
# Returns the +i18n_scope+ for the class. Overwrite if you want custom lookup.
|
2374
|
-
def i18n_scope: () -> :activemodel
|
2375
|
-
|
2376
|
-
# When localizing a string, it goes through the lookup returned by this
|
2377
|
-
# method, which is used in ActiveModel::Name#human,
|
2378
|
-
# ActiveModel::Errors#full_messages and
|
2379
|
-
# ActiveModel::Translation#human_attribute_name.
|
2380
|
-
def lookup_ancestors: () -> untyped
|
2381
|
-
|
2382
|
-
# Transforms attribute names into a more human format, such as "First name"
|
2383
|
-
# instead of "first_name".
|
2384
|
-
#
|
2385
|
-
# Person.human_attribute_name("first_name") # => "First name"
|
2386
|
-
#
|
2387
|
-
# Specify +options+ with additional translating options.
|
2388
|
-
def human_attribute_name: (untyped attribute, ?::Hash[untyped, untyped] options) -> untyped
|
2389
|
-
end
|
2390
|
-
end
|
2391
|
-
|
2392
|
-
module ActiveModel
|
2393
|
-
module Type
|
2394
|
-
class BigInteger < Integer
|
2395
|
-
def max_value: () -> untyped
|
2396
|
-
end
|
2397
|
-
end
|
2398
|
-
end
|
2399
|
-
|
2400
|
-
module ActiveModel
|
2401
|
-
module Type
|
2402
|
-
class Binary < Value
|
2403
|
-
# :nodoc:
|
2404
|
-
def `type`: () -> :binary
|
2405
|
-
|
2406
|
-
def binary?: () -> ::TrueClass
|
2407
|
-
|
2408
|
-
def cast: (untyped value) -> untyped
|
2409
|
-
|
2410
|
-
def serialize: (untyped value) -> (nil | Data)
|
2411
|
-
|
2412
|
-
def changed_in_place?: (untyped raw_old_value, untyped value) -> untyped
|
2413
|
-
|
2414
|
-
class Data
|
2415
|
-
# :nodoc:
|
2416
|
-
def initialize: (untyped value) -> untyped
|
2417
|
-
|
2418
|
-
def to_s: () -> untyped
|
2419
|
-
|
2420
|
-
alias to_str to_s
|
2421
|
-
|
2422
|
-
def hex: () -> untyped
|
2423
|
-
|
2424
|
-
def ==: (untyped other) -> untyped
|
2425
|
-
end
|
2426
|
-
end
|
2427
|
-
end
|
2428
|
-
end
|
2429
|
-
|
2430
|
-
module ActiveModel
|
2431
|
-
module Type
|
2432
|
-
# == Active \Model \Type \Boolean
|
2433
|
-
#
|
2434
|
-
# A class that behaves like a boolean type, including rules for coercion of user input.
|
2435
|
-
#
|
2436
|
-
# === Coercion
|
2437
|
-
# Values set from user input will first be coerced into the appropriate ruby type.
|
2438
|
-
# Coercion behavior is roughly mapped to Ruby's boolean semantics.
|
2439
|
-
#
|
2440
|
-
# - "false", "f" , "0", +0+ or any other value in +FALSE_VALUES+ will be coerced to +false+
|
2441
|
-
# - Empty strings are coerced to +nil+
|
2442
|
-
# - All other values will be coerced to +true+
|
2443
|
-
class Boolean < Value
|
2444
|
-
FALSE_VALUES: untyped
|
2445
|
-
|
2446
|
-
def `type`: () -> :boolean
|
2447
|
-
|
2448
|
-
def serialize: (untyped value) -> untyped
|
2449
|
-
|
2450
|
-
def cast_value: (untyped value) -> untyped
|
2451
|
-
end
|
2452
|
-
end
|
2453
|
-
end
|
2454
|
-
|
2455
|
-
module ActiveModel
|
2456
|
-
module Type
|
2457
|
-
class Date < Value
|
2458
|
-
# :nodoc:
|
2459
|
-
include Helpers::Timezone
|
2460
|
-
|
2461
|
-
def `type`: () -> :date
|
2462
|
-
|
2463
|
-
def type_cast_for_schema: (untyped value) -> untyped
|
2464
|
-
|
2465
|
-
def cast_value: (untyped value) -> untyped
|
2466
|
-
|
2467
|
-
ISO_DATE: untyped
|
2468
|
-
|
2469
|
-
def fast_string_to_date: (untyped string) -> untyped
|
2470
|
-
|
2471
|
-
def fallback_string_to_date: (untyped string) -> untyped
|
2472
|
-
|
2473
|
-
def new_date: (untyped year, untyped mon, untyped mday) -> untyped
|
2474
|
-
|
2475
|
-
def value_from_multiparameter_assignment: () -> untyped
|
2476
|
-
end
|
2477
|
-
end
|
2478
|
-
end
|
2479
|
-
|
2480
|
-
module ActiveModel
|
2481
|
-
module Type
|
2482
|
-
class DateTime < Value
|
2483
|
-
# :nodoc:
|
2484
|
-
include Helpers::Timezone
|
2485
|
-
|
2486
|
-
include Helpers::TimeValue
|
2487
|
-
|
2488
|
-
def `type`: () -> :datetime
|
2489
|
-
|
2490
|
-
def cast_value: (untyped value) -> (untyped | nil)
|
2491
|
-
|
2492
|
-
# '0.123456' -> 123456
|
2493
|
-
# '1.123456' -> 123456
|
2494
|
-
def microseconds: (untyped time) -> untyped
|
2495
|
-
|
2496
|
-
def fallback_string_to_time: (untyped string) -> untyped
|
2497
|
-
|
2498
|
-
def value_from_multiparameter_assignment: (untyped values_hash) -> untyped
|
2499
|
-
end
|
2500
|
-
end
|
2501
|
-
end
|
2502
|
-
|
2503
|
-
module ActiveModel
|
2504
|
-
module Type
|
2505
|
-
class Decimal < Value
|
2506
|
-
# :nodoc:
|
2507
|
-
include Helpers::Numeric
|
2508
|
-
|
2509
|
-
BIGDECIMAL_PRECISION: ::Integer
|
2510
|
-
|
2511
|
-
def `type`: () -> :decimal
|
2512
|
-
|
2513
|
-
def type_cast_for_schema: (untyped value) -> untyped
|
2514
|
-
|
2515
|
-
def cast_value: (untyped value) -> untyped
|
2516
|
-
|
2517
|
-
def convert_float_to_big_decimal: (untyped value) -> untyped
|
2518
|
-
|
2519
|
-
def float_precision: () -> untyped
|
2520
|
-
|
2521
|
-
def apply_scale: (untyped value) -> untyped
|
2522
|
-
end
|
2523
|
-
end
|
2524
|
-
end
|
2525
|
-
|
2526
|
-
module ActiveModel
|
2527
|
-
module Type
|
2528
|
-
class Float < Value
|
2529
|
-
# :nodoc:
|
2530
|
-
include Helpers::Numeric
|
2531
|
-
|
2532
|
-
def `type`: () -> :float
|
2533
|
-
|
2534
|
-
def type_cast_for_schema: (untyped value) -> ("::Float::NAN" | untyped)
|
2535
|
-
|
2536
|
-
def cast_value: (untyped value) -> untyped
|
2537
|
-
end
|
2538
|
-
end
|
2539
|
-
end
|
2540
|
-
|
2541
|
-
module ActiveModel
|
2542
|
-
module Type
|
2543
|
-
module Helpers
|
2544
|
-
# :nodoc: all
|
2545
|
-
class AcceptsMultiparameterTime < Module
|
2546
|
-
def initialize: (?defaults: ::Hash[untyped, untyped] defaults) -> (nil | untyped)
|
2547
|
-
end
|
2548
|
-
end
|
2549
|
-
end
|
2550
|
-
end
|
2551
|
-
|
2552
|
-
module ActiveModel
|
2553
|
-
module Type
|
2554
|
-
module Helpers
|
2555
|
-
# :nodoc: all
|
2556
|
-
module Mutable
|
2557
|
-
def cast: (untyped value) -> untyped
|
2558
|
-
|
2559
|
-
# +raw_old_value+ will be the `_before_type_cast` version of the
|
2560
|
-
# value (likely a string). +new_value+ will be the current, type
|
2561
|
-
# cast value.
|
2562
|
-
def changed_in_place?: (untyped raw_old_value, untyped new_value) -> untyped
|
2563
|
-
end
|
2564
|
-
end
|
2565
|
-
end
|
2566
|
-
end
|
2567
|
-
|
2568
|
-
module ActiveModel
|
2569
|
-
module Type
|
2570
|
-
module Helpers
|
2571
|
-
# :nodoc: all
|
2572
|
-
module Numeric
|
2573
|
-
def serialize: (untyped value) -> untyped
|
2574
|
-
|
2575
|
-
def cast: (untyped value) -> untyped
|
2576
|
-
|
2577
|
-
def changed?: (untyped old_value, untyped _new_value, untyped new_value_before_type_cast) -> untyped
|
2578
|
-
|
2579
|
-
def number_to_non_number?: (untyped old_value, untyped new_value_before_type_cast) -> untyped
|
2580
|
-
|
2581
|
-
def non_numeric_string?: (untyped value) -> untyped
|
2582
|
-
|
2583
|
-
NUMERIC_REGEX: untyped
|
2584
|
-
end
|
2585
|
-
end
|
2586
|
-
end
|
2587
|
-
end
|
2588
|
-
|
2589
|
-
module ActiveModel
|
2590
|
-
module Type
|
2591
|
-
module Helpers
|
2592
|
-
# :nodoc: all
|
2593
|
-
module TimeValue
|
2594
|
-
def serialize: (untyped value) -> untyped
|
2595
|
-
|
2596
|
-
def apply_seconds_precision: (untyped value) -> untyped
|
2597
|
-
|
2598
|
-
def type_cast_for_schema: (untyped value) -> untyped
|
2599
|
-
|
2600
|
-
def user_input_in_time_zone: (untyped value) -> untyped
|
2601
|
-
|
2602
|
-
def new_time: (untyped year, untyped mon, untyped mday, untyped hour, untyped min, untyped sec, untyped microsec, ?untyped? offset) -> (nil | untyped)
|
2603
|
-
|
2604
|
-
ISO_DATETIME: untyped
|
2605
|
-
|
2606
|
-
# Doesn't handle time zones.
|
2607
|
-
def fast_string_to_time: (untyped string) -> untyped
|
2608
|
-
end
|
2609
|
-
end
|
2610
|
-
end
|
2611
|
-
end
|
2612
|
-
|
2613
|
-
module ActiveModel
|
2614
|
-
module Type
|
2615
|
-
module Helpers
|
2616
|
-
# :nodoc: all
|
2617
|
-
module Timezone
|
2618
|
-
def is_utc?: () -> untyped
|
2619
|
-
|
2620
|
-
def default_timezone: () -> untyped
|
2621
|
-
end
|
2622
|
-
end
|
2623
|
-
end
|
2624
|
-
end
|
2625
|
-
|
2626
|
-
module ActiveModel
|
2627
|
-
module Type
|
2628
|
-
class ImmutableString < Value
|
2629
|
-
# :nodoc:
|
2630
|
-
def `type`: () -> :string
|
2631
|
-
|
2632
|
-
def serialize: (untyped value) -> untyped
|
2633
|
-
|
2634
|
-
def cast_value: (untyped value) -> untyped
|
2635
|
-
end
|
2636
|
-
end
|
2637
|
-
end
|
2638
|
-
|
2639
|
-
module ActiveModel
|
2640
|
-
module Type
|
2641
|
-
class Integer < Value
|
2642
|
-
# :nodoc:
|
2643
|
-
include Helpers::Numeric
|
2644
|
-
|
2645
|
-
# Column storage size in bytes.
|
2646
|
-
# 4 bytes means an integer as opposed to smallint etc.
|
2647
|
-
DEFAULT_LIMIT: ::Integer
|
2648
|
-
|
2649
|
-
def initialize: () -> untyped
|
2650
|
-
|
2651
|
-
def `type`: () -> :integer
|
2652
|
-
|
2653
|
-
def deserialize: (untyped value) -> (nil | untyped)
|
2654
|
-
|
2655
|
-
def serialize: (untyped value) -> (nil | untyped)
|
2656
|
-
|
2657
|
-
attr_reader range: untyped
|
2658
|
-
|
2659
|
-
def cast_value: (untyped value) -> untyped
|
2660
|
-
|
2661
|
-
def ensure_in_range: (untyped value) -> untyped
|
2662
|
-
|
2663
|
-
def max_value: () -> untyped
|
2664
|
-
|
2665
|
-
def min_value: () -> untyped
|
2666
|
-
|
2667
|
-
def _limit: () -> untyped
|
2668
|
-
end
|
2669
|
-
end
|
2670
|
-
end
|
2671
|
-
|
2672
|
-
module ActiveModel
|
2673
|
-
# :stopdoc:
|
2674
|
-
module Type
|
2675
|
-
class Registry
|
2676
|
-
def initialize: () -> untyped
|
2677
|
-
|
2678
|
-
def register: (untyped type_name, ?untyped? klass, **untyped options) { () -> untyped } -> untyped
|
2679
|
-
|
2680
|
-
def lookup: (untyped symbol, *untyped args, **untyped kwargs) -> untyped
|
2681
|
-
|
2682
|
-
attr_reader registrations: untyped
|
2683
|
-
|
2684
|
-
def registration_klass: () -> untyped
|
2685
|
-
|
2686
|
-
def find_registration: (untyped symbol, *untyped args) -> untyped
|
2687
|
-
end
|
2688
|
-
|
2689
|
-
class Registration
|
2690
|
-
# Options must be taken because of https://bugs.ruby-lang.org/issues/10856
|
2691
|
-
def initialize: (untyped name, untyped block) -> untyped
|
2692
|
-
|
2693
|
-
def call: (untyped _registry, *untyped args, **untyped kwargs) -> untyped
|
2694
|
-
|
2695
|
-
def matches?: (untyped type_name, *untyped args, **untyped kwargs) -> untyped
|
2696
|
-
|
2697
|
-
attr_reader name: untyped
|
2698
|
-
|
2699
|
-
attr_reader block: untyped
|
2700
|
-
end
|
2701
|
-
end
|
2702
|
-
end
|
2703
|
-
|
2704
|
-
module ActiveModel
|
2705
|
-
module Type
|
2706
|
-
class String < ImmutableString
|
2707
|
-
# :nodoc:
|
2708
|
-
def changed_in_place?: (untyped raw_old_value, untyped new_value) -> untyped
|
2709
|
-
|
2710
|
-
def cast_value: (untyped value) -> untyped
|
2711
|
-
end
|
2712
|
-
end
|
2713
|
-
end
|
2714
|
-
|
2715
|
-
module ActiveModel
|
2716
|
-
module Type
|
2717
|
-
class Time < Value
|
2718
|
-
# :nodoc:
|
2719
|
-
include Helpers::Timezone
|
2720
|
-
|
2721
|
-
include Helpers::TimeValue
|
2722
|
-
|
2723
|
-
def `type`: () -> :time
|
2724
|
-
|
2725
|
-
def user_input_in_time_zone: (untyped value) -> (nil | untyped)
|
2726
|
-
|
2727
|
-
def cast_value: (untyped value) -> (untyped | nil)
|
2728
|
-
end
|
2729
|
-
end
|
2730
|
-
end
|
2731
|
-
|
2732
|
-
module ActiveModel
|
2733
|
-
module Type
|
2734
|
-
class Value
|
2735
|
-
attr_reader precision: untyped
|
2736
|
-
|
2737
|
-
attr_reader scale: untyped
|
2738
|
-
|
2739
|
-
attr_reader limit: untyped
|
2740
|
-
|
2741
|
-
def initialize: (?precision: untyped? precision, ?limit: untyped? limit, ?scale: untyped? scale) -> untyped
|
2742
|
-
|
2743
|
-
def `type`: () -> nil
|
2744
|
-
|
2745
|
-
# Converts a value from database input to the appropriate ruby type. The
|
2746
|
-
# return value of this method will be returned from
|
2747
|
-
# ActiveRecord::AttributeMethods::Read#read_attribute. The default
|
2748
|
-
# implementation just calls Value#cast.
|
2749
|
-
#
|
2750
|
-
# +value+ The raw input, as provided from the database.
|
2751
|
-
def deserialize: (untyped value) -> untyped
|
2752
|
-
|
2753
|
-
# Type casts a value from user input (e.g. from a setter). This value may
|
2754
|
-
# be a string from the form builder, or a ruby object passed to a setter.
|
2755
|
-
# There is currently no way to differentiate between which source it came
|
2756
|
-
# from.
|
2757
|
-
#
|
2758
|
-
# The return value of this method will be returned from
|
2759
|
-
# ActiveRecord::AttributeMethods::Read#read_attribute. See also:
|
2760
|
-
# Value#cast_value.
|
2761
|
-
#
|
2762
|
-
# +value+ The raw input, as provided to the attribute setter.
|
2763
|
-
def cast: (untyped value) -> untyped
|
2764
|
-
|
2765
|
-
# Casts a value from the ruby type to a type that the database knows how
|
2766
|
-
# to understand. The returned value from this method should be a
|
2767
|
-
# +String+, +Numeric+, +Date+, +Time+, +Symbol+, +true+, +false+, or
|
2768
|
-
# +nil+.
|
2769
|
-
def serialize: (untyped value) -> untyped
|
2770
|
-
|
2771
|
-
def type_cast_for_schema: (untyped value) -> untyped
|
2772
|
-
|
2773
|
-
def binary?: () -> ::FalseClass
|
2774
|
-
|
2775
|
-
# Determines whether a value has changed for dirty checking. +old_value+
|
2776
|
-
# and +new_value+ will always be type-cast. Types should not need to
|
2777
|
-
# override this method.
|
2778
|
-
def changed?: (untyped old_value, untyped new_value, untyped _new_value_before_type_cast) -> untyped
|
2779
|
-
|
2780
|
-
# Determines whether the mutable value has been modified since it was
|
2781
|
-
# read. Returns +false+ by default. If your type returns an object
|
2782
|
-
# which could be mutated, you should override this method. You will need
|
2783
|
-
# to either:
|
2784
|
-
#
|
2785
|
-
# - pass +new_value+ to Value#serialize and compare it to
|
2786
|
-
# +raw_old_value+
|
2787
|
-
#
|
2788
|
-
# or
|
2789
|
-
#
|
2790
|
-
# - pass +raw_old_value+ to Value#deserialize and compare it to
|
2791
|
-
# +new_value+
|
2792
|
-
#
|
2793
|
-
# +raw_old_value+ The original value, before being passed to
|
2794
|
-
# +deserialize+.
|
2795
|
-
#
|
2796
|
-
# +new_value+ The current value, after type casting.
|
2797
|
-
def changed_in_place?: (untyped raw_old_value, untyped new_value) -> ::FalseClass
|
2798
|
-
|
2799
|
-
def value_constructed_by_mass_assignment?: (untyped _value) -> ::FalseClass
|
2800
|
-
|
2801
|
-
def force_equality?: (untyped _value) -> ::FalseClass
|
2802
|
-
|
2803
|
-
def map: (untyped value) { (untyped) -> untyped } -> untyped
|
2804
|
-
|
2805
|
-
def ==: (untyped other) -> untyped
|
2806
|
-
|
2807
|
-
alias eql? ==
|
2808
|
-
|
2809
|
-
def hash: () -> untyped
|
2810
|
-
|
2811
|
-
def assert_valid_value: () -> nil
|
2812
|
-
|
2813
|
-
def cast_value: (untyped value) -> untyped
|
2814
|
-
end
|
2815
|
-
end
|
2816
|
-
end
|
2817
|
-
|
2818
|
-
module ActiveModel
|
2819
|
-
module Type
|
2820
|
-
attr_accessor registry: untyped
|
2821
|
-
|
2822
|
-
# Add a new type to the registry, allowing it to be gotten through ActiveModel::Type#lookup
|
2823
|
-
def self.register: (untyped type_name, ?untyped? klass, **untyped options) { () -> untyped } -> untyped
|
2824
|
-
|
2825
|
-
def self.lookup: (*untyped args, **untyped kwargs) -> untyped
|
2826
|
-
|
2827
|
-
def self.default_value: () -> untyped
|
2828
|
-
end
|
2829
|
-
end
|
2830
|
-
|
2831
|
-
module ActiveModel
|
2832
|
-
module Validations
|
2833
|
-
class AbsenceValidator < EachValidator
|
2834
|
-
# == \Active \Model Absence Validator
|
2835
|
-
# nodoc:
|
2836
|
-
def validate_each: (untyped record, untyped attr_name, untyped value) -> untyped
|
2837
|
-
end
|
2838
|
-
|
2839
|
-
module HelperMethods
|
2840
|
-
# Validates that the specified attributes are blank (as defined by
|
2841
|
-
# Object#present?). Happens by default on save.
|
2842
|
-
#
|
2843
|
-
# class Person < ActiveRecord::Base
|
2844
|
-
# validates_absence_of :first_name
|
2845
|
-
# end
|
2846
|
-
#
|
2847
|
-
# The first_name attribute must be in the object and it must be blank.
|
2848
|
-
#
|
2849
|
-
# Configuration options:
|
2850
|
-
# * <tt>:message</tt> - A custom error message (default is: "must be blank").
|
2851
|
-
#
|
2852
|
-
# There is also a list of default options supported by every validator:
|
2853
|
-
# +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+.
|
2854
|
-
# See <tt>ActiveModel::Validations#validates</tt> for more information
|
2855
|
-
def validates_absence_of: (*untyped attr_names) -> untyped
|
2856
|
-
end
|
2857
|
-
end
|
2858
|
-
end
|
2859
|
-
|
2860
|
-
module ActiveModel
|
2861
|
-
module Validations
|
2862
|
-
class AcceptanceValidator < EachValidator
|
2863
|
-
# :nodoc:
|
2864
|
-
def initialize: (untyped options) -> untyped
|
2865
|
-
|
2866
|
-
def validate_each: (untyped record, untyped attribute, untyped value) -> untyped
|
2867
|
-
|
2868
|
-
def setup!: (untyped klass) -> untyped
|
2869
|
-
|
2870
|
-
def acceptable_option?: (untyped value) -> untyped
|
2871
|
-
|
2872
|
-
class LazilyDefineAttributes < Module
|
2873
|
-
def initialize: (untyped attributes) -> untyped
|
2874
|
-
|
2875
|
-
def included: (untyped klass) -> untyped
|
2876
|
-
|
2877
|
-
def matches?: (untyped method_name) -> untyped
|
2878
|
-
|
2879
|
-
def define_on: (untyped klass) -> untyped
|
2880
|
-
|
2881
|
-
def ==: (untyped other) -> untyped
|
2882
|
-
|
2883
|
-
attr_reader attributes: untyped
|
2884
|
-
end
|
2885
|
-
end
|
2886
|
-
|
2887
|
-
module HelperMethods
|
2888
|
-
# Encapsulates the pattern of wanting to validate the acceptance of a
|
2889
|
-
# terms of service check box (or similar agreement).
|
2890
|
-
#
|
2891
|
-
# class Person < ActiveRecord::Base
|
2892
|
-
# validates_acceptance_of :terms_of_service
|
2893
|
-
# validates_acceptance_of :eula, message: 'must be abided'
|
2894
|
-
# end
|
2895
|
-
#
|
2896
|
-
# If the database column does not exist, the +terms_of_service+ attribute
|
2897
|
-
# is entirely virtual. This check is performed only if +terms_of_service+
|
2898
|
-
# is not +nil+ and by default on save.
|
2899
|
-
#
|
2900
|
-
# Configuration options:
|
2901
|
-
# * <tt>:message</tt> - A custom error message (default is: "must be
|
2902
|
-
# accepted").
|
2903
|
-
# * <tt>:accept</tt> - Specifies a value that is considered accepted.
|
2904
|
-
# Also accepts an array of possible values. The default value is
|
2905
|
-
# an array ["1", true], which makes it easy to relate to an HTML
|
2906
|
-
# checkbox. This should be set to, or include, +true+ if you are validating
|
2907
|
-
# a database column, since the attribute is typecast from "1" to +true+
|
2908
|
-
# before validation.
|
2909
|
-
#
|
2910
|
-
# There is also a list of default options supported by every validator:
|
2911
|
-
# +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+.
|
2912
|
-
# See <tt>ActiveModel::Validations#validates</tt> for more information.
|
2913
|
-
def validates_acceptance_of: (*untyped attr_names) -> untyped
|
2914
|
-
end
|
2915
|
-
end
|
2916
|
-
end
|
2917
|
-
|
2918
|
-
module ActiveModel
|
2919
|
-
module Validations
|
2920
|
-
# == Active \Model \Validation \Callbacks
|
2921
|
-
#
|
2922
|
-
# Provides an interface for any class to have +before_validation+ and
|
2923
|
-
# +after_validation+ callbacks.
|
2924
|
-
#
|
2925
|
-
# First, include ActiveModel::Validations::Callbacks from the class you are
|
2926
|
-
# creating:
|
2927
|
-
#
|
2928
|
-
# class MyModel
|
2929
|
-
# include ActiveModel::Validations::Callbacks
|
2930
|
-
#
|
2931
|
-
# before_validation :do_stuff_before_validation
|
2932
|
-
# after_validation :do_stuff_after_validation
|
2933
|
-
# end
|
2934
|
-
#
|
2935
|
-
# Like other <tt>before_*</tt> callbacks if +before_validation+ throws
|
2936
|
-
# +:abort+ then <tt>valid?</tt> will not be called.
|
2937
|
-
module Callbacks
|
2938
|
-
extend ActiveSupport::Concern
|
2939
|
-
|
2940
|
-
include ActiveSupport::Callbacks
|
2941
|
-
|
2942
|
-
extend ::ActiveSupport::Callbacks::ClassMethods
|
2943
|
-
|
2944
|
-
module ClassMethods
|
2945
|
-
# Defines a callback that will get called right before validation.
|
2946
|
-
#
|
2947
|
-
# class Person
|
2948
|
-
# include ActiveModel::Validations
|
2949
|
-
# include ActiveModel::Validations::Callbacks
|
2950
|
-
#
|
2951
|
-
# attr_accessor :name
|
2952
|
-
#
|
2953
|
-
# validates_length_of :name, maximum: 6
|
2954
|
-
#
|
2955
|
-
# before_validation :remove_whitespaces
|
2956
|
-
#
|
2957
|
-
# private
|
2958
|
-
#
|
2959
|
-
# def remove_whitespaces
|
2960
|
-
# name.strip!
|
2961
|
-
# end
|
2962
|
-
# end
|
2963
|
-
#
|
2964
|
-
# person = Person.new
|
2965
|
-
# person.name = ' bob '
|
2966
|
-
# person.valid? # => true
|
2967
|
-
# person.name # => "bob"
|
2968
|
-
def before_validation: (*untyped args) { () -> untyped } -> untyped
|
2969
|
-
|
2970
|
-
# Defines a callback that will get called right after validation.
|
2971
|
-
#
|
2972
|
-
# class Person
|
2973
|
-
# include ActiveModel::Validations
|
2974
|
-
# include ActiveModel::Validations::Callbacks
|
2975
|
-
#
|
2976
|
-
# attr_accessor :name, :status
|
2977
|
-
#
|
2978
|
-
# validates_presence_of :name
|
2979
|
-
#
|
2980
|
-
# after_validation :set_status
|
2981
|
-
#
|
2982
|
-
# private
|
2983
|
-
#
|
2984
|
-
# def set_status
|
2985
|
-
# self.status = errors.empty?
|
2986
|
-
# end
|
2987
|
-
# end
|
2988
|
-
#
|
2989
|
-
# person = Person.new
|
2990
|
-
# person.name = ''
|
2991
|
-
# person.valid? # => false
|
2992
|
-
# person.status # => false
|
2993
|
-
# person.name = 'bob'
|
2994
|
-
# person.valid? # => true
|
2995
|
-
# person.status # => true
|
2996
|
-
def after_validation: (*untyped args) { () -> untyped } -> untyped
|
2997
|
-
end
|
2998
|
-
|
2999
|
-
# Overwrite run validations to include callbacks.
|
3000
|
-
def run_validations!: () -> untyped
|
3001
|
-
end
|
3002
|
-
end
|
3003
|
-
end
|
3004
|
-
|
3005
|
-
module ActiveModel
|
3006
|
-
module Validations
|
3007
|
-
module Clusivity
|
3008
|
-
# nodoc:
|
3009
|
-
ERROR_MESSAGE: ::String
|
3010
|
-
|
3011
|
-
def check_validity!: () -> untyped
|
3012
|
-
|
3013
|
-
def include?: (untyped record, untyped value) -> untyped
|
3014
|
-
|
3015
|
-
def delimiter: () -> untyped
|
3016
|
-
|
3017
|
-
# After Ruby 2.2, <tt>Range#include?</tt> on non-number-or-time-ish ranges checks all
|
3018
|
-
# possible values in the range for equality, which is slower but more accurate.
|
3019
|
-
# <tt>Range#cover?</tt> uses the previous logic of comparing a value with the range
|
3020
|
-
# endpoints, which is fast but is only accurate on Numeric, Time, Date,
|
3021
|
-
# or DateTime ranges.
|
3022
|
-
def inclusion_method: (untyped enumerable) -> untyped
|
3023
|
-
end
|
3024
|
-
end
|
3025
|
-
end
|
3026
|
-
|
3027
|
-
module ActiveModel
|
3028
|
-
module Validations
|
3029
|
-
class ConfirmationValidator < EachValidator
|
3030
|
-
# :nodoc:
|
3031
|
-
def initialize: (untyped options) -> untyped
|
3032
|
-
|
3033
|
-
def validate_each: (untyped record, untyped attribute, untyped value) -> untyped
|
3034
|
-
|
3035
|
-
def setup!: (untyped klass) -> untyped
|
3036
|
-
|
3037
|
-
def confirmation_value_equal?: (untyped record, untyped attribute, untyped value, untyped confirmed) -> untyped
|
3038
|
-
end
|
3039
|
-
|
3040
|
-
module HelperMethods
|
3041
|
-
# Encapsulates the pattern of wanting to validate a password or email
|
3042
|
-
# address field with a confirmation.
|
3043
|
-
#
|
3044
|
-
# Model:
|
3045
|
-
# class Person < ActiveRecord::Base
|
3046
|
-
# validates_confirmation_of :user_name, :password
|
3047
|
-
# validates_confirmation_of :email_address,
|
3048
|
-
# message: 'should match confirmation'
|
3049
|
-
# end
|
3050
|
-
#
|
3051
|
-
# View:
|
3052
|
-
# <%= password_field "person", "password" %>
|
3053
|
-
# <%= password_field "person", "password_confirmation" %>
|
3054
|
-
#
|
3055
|
-
# The added +password_confirmation+ attribute is virtual; it exists only
|
3056
|
-
# as an in-memory attribute for validating the password. To achieve this,
|
3057
|
-
# the validation adds accessors to the model for the confirmation
|
3058
|
-
# attribute.
|
3059
|
-
#
|
3060
|
-
# NOTE: This check is performed only if +password_confirmation+ is not
|
3061
|
-
# +nil+. To require confirmation, make sure to add a presence check for
|
3062
|
-
# the confirmation attribute:
|
3063
|
-
#
|
3064
|
-
# validates_presence_of :password_confirmation, if: :password_changed?
|
3065
|
-
#
|
3066
|
-
# Configuration options:
|
3067
|
-
# * <tt>:message</tt> - A custom error message (default is: "doesn't match
|
3068
|
-
# <tt>%{translated_attribute_name}</tt>").
|
3069
|
-
# * <tt>:case_sensitive</tt> - Looks for an exact match. Ignored by
|
3070
|
-
# non-text columns (+true+ by default).
|
3071
|
-
#
|
3072
|
-
# There is also a list of default options supported by every validator:
|
3073
|
-
# +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+.
|
3074
|
-
# See <tt>ActiveModel::Validations#validates</tt> for more information
|
3075
|
-
def validates_confirmation_of: (*untyped attr_names) -> untyped
|
3076
|
-
end
|
3077
|
-
end
|
3078
|
-
end
|
3079
|
-
|
3080
|
-
module ActiveModel
|
3081
|
-
module Validations
|
3082
|
-
class ExclusionValidator < EachValidator
|
3083
|
-
# :nodoc:
|
3084
|
-
include Clusivity
|
3085
|
-
|
3086
|
-
def validate_each: (untyped record, untyped attribute, untyped value) -> untyped
|
3087
|
-
end
|
3088
|
-
|
3089
|
-
module HelperMethods
|
3090
|
-
# Validates that the value of the specified attribute is not in a
|
3091
|
-
# particular enumerable object.
|
3092
|
-
#
|
3093
|
-
# class Person < ActiveRecord::Base
|
3094
|
-
# validates_exclusion_of :username, in: %w( admin superuser ), message: "You don't belong here"
|
3095
|
-
# validates_exclusion_of :age, in: 30..60, message: 'This site is only for under 30 and over 60'
|
3096
|
-
# validates_exclusion_of :format, in: %w( mov avi ), message: "extension %{value} is not allowed"
|
3097
|
-
# validates_exclusion_of :password, in: ->(person) { [person.username, person.first_name] },
|
3098
|
-
# message: 'should not be the same as your username or first name'
|
3099
|
-
# validates_exclusion_of :karma, in: :reserved_karmas
|
3100
|
-
# end
|
3101
|
-
#
|
3102
|
-
# Configuration options:
|
3103
|
-
# * <tt>:in</tt> - An enumerable object of items that the value shouldn't
|
3104
|
-
# be part of. This can be supplied as a proc, lambda or symbol which returns an
|
3105
|
-
# enumerable. If the enumerable is a numerical, time or datetime range the test
|
3106
|
-
# is performed with <tt>Range#cover?</tt>, otherwise with <tt>include?</tt>. When
|
3107
|
-
# using a proc or lambda the instance under validation is passed as an argument.
|
3108
|
-
# * <tt>:within</tt> - A synonym(or alias) for <tt>:in</tt>
|
3109
|
-
# <tt>Range#cover?</tt>, otherwise with <tt>include?</tt>.
|
3110
|
-
# * <tt>:message</tt> - Specifies a custom error message (default is: "is
|
3111
|
-
# reserved").
|
3112
|
-
#
|
3113
|
-
# There is also a list of default options supported by every validator:
|
3114
|
-
# +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+.
|
3115
|
-
# See <tt>ActiveModel::Validations#validates</tt> for more information
|
3116
|
-
def validates_exclusion_of: (*untyped attr_names) -> untyped
|
3117
|
-
end
|
3118
|
-
end
|
3119
|
-
end
|
3120
|
-
|
3121
|
-
module ActiveModel
|
3122
|
-
module Validations
|
3123
|
-
class FormatValidator < EachValidator
|
3124
|
-
# :nodoc:
|
3125
|
-
def validate_each: (untyped record, untyped attribute, untyped value) -> untyped
|
3126
|
-
|
3127
|
-
def check_validity!: () -> untyped
|
3128
|
-
|
3129
|
-
def option_call: (untyped record, untyped name) -> untyped
|
3130
|
-
|
3131
|
-
def record_error: (untyped record, untyped attribute, untyped name, untyped value) -> untyped
|
3132
|
-
|
3133
|
-
def check_options_validity: (untyped name) -> untyped
|
3134
|
-
|
3135
|
-
def regexp_using_multiline_anchors?: (untyped regexp) -> untyped
|
3136
|
-
end
|
3137
|
-
|
3138
|
-
module HelperMethods
|
3139
|
-
# Validates whether the value of the specified attribute is of the correct
|
3140
|
-
# form, going by the regular expression provided. You can require that the
|
3141
|
-
# attribute matches the regular expression:
|
3142
|
-
#
|
3143
|
-
# class Person < ActiveRecord::Base
|
3144
|
-
# validates_format_of :email, with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, on: :create
|
3145
|
-
# end
|
3146
|
-
#
|
3147
|
-
# Alternatively, you can require that the specified attribute does _not_
|
3148
|
-
# match the regular expression:
|
3149
|
-
#
|
3150
|
-
# class Person < ActiveRecord::Base
|
3151
|
-
# validates_format_of :email, without: /NOSPAM/
|
3152
|
-
# end
|
3153
|
-
#
|
3154
|
-
# You can also provide a proc or lambda which will determine the regular
|
3155
|
-
# expression that will be used to validate the attribute.
|
3156
|
-
#
|
3157
|
-
# class Person < ActiveRecord::Base
|
3158
|
-
# # Admin can have number as a first letter in their screen name
|
3159
|
-
# validates_format_of :screen_name,
|
3160
|
-
# with: ->(person) { person.admin? ? /\A[a-z0-9][a-z0-9_\-]*\z/i : /\A[a-z][a-z0-9_\-]*\z/i }
|
3161
|
-
# end
|
3162
|
-
#
|
3163
|
-
# Note: use <tt>\A</tt> and <tt>\z</tt> to match the start and end of the
|
3164
|
-
# string, <tt>^</tt> and <tt>$</tt> match the start/end of a line.
|
3165
|
-
#
|
3166
|
-
# Due to frequent misuse of <tt>^</tt> and <tt>$</tt>, you need to pass
|
3167
|
-
# the <tt>multiline: true</tt> option in case you use any of these two
|
3168
|
-
# anchors in the provided regular expression. In most cases, you should be
|
3169
|
-
# using <tt>\A</tt> and <tt>\z</tt>.
|
3170
|
-
#
|
3171
|
-
# You must pass either <tt>:with</tt> or <tt>:without</tt> as an option.
|
3172
|
-
# In addition, both must be a regular expression or a proc or lambda, or
|
3173
|
-
# else an exception will be raised.
|
3174
|
-
#
|
3175
|
-
# Configuration options:
|
3176
|
-
# * <tt>:message</tt> - A custom error message (default is: "is invalid").
|
3177
|
-
# * <tt>:with</tt> - Regular expression that if the attribute matches will
|
3178
|
-
# result in a successful validation. This can be provided as a proc or
|
3179
|
-
# lambda returning regular expression which will be called at runtime.
|
3180
|
-
# * <tt>:without</tt> - Regular expression that if the attribute does not
|
3181
|
-
# match will result in a successful validation. This can be provided as
|
3182
|
-
# a proc or lambda returning regular expression which will be called at
|
3183
|
-
# runtime.
|
3184
|
-
# * <tt>:multiline</tt> - Set to true if your regular expression contains
|
3185
|
-
# anchors that match the beginning or end of lines as opposed to the
|
3186
|
-
# beginning or end of the string. These anchors are <tt>^</tt> and <tt>$</tt>.
|
3187
|
-
#
|
3188
|
-
# There is also a list of default options supported by every validator:
|
3189
|
-
# +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+.
|
3190
|
-
# See <tt>ActiveModel::Validations#validates</tt> for more information
|
3191
|
-
def validates_format_of: (*untyped attr_names) -> untyped
|
3192
|
-
end
|
3193
|
-
end
|
3194
|
-
end
|
3195
|
-
|
3196
|
-
module ActiveModel
|
3197
|
-
module Validations
|
3198
|
-
module HelperMethods
|
3199
|
-
def _merge_attributes: (untyped attr_names) -> untyped
|
3200
|
-
end
|
3201
|
-
end
|
3202
|
-
end
|
3203
|
-
|
3204
|
-
module ActiveModel
|
3205
|
-
module Validations
|
3206
|
-
class InclusionValidator < EachValidator
|
3207
|
-
# :nodoc:
|
3208
|
-
include Clusivity
|
3209
|
-
|
3210
|
-
def validate_each: (untyped record, untyped attribute, untyped value) -> untyped
|
3211
|
-
end
|
3212
|
-
|
3213
|
-
module HelperMethods
|
3214
|
-
# Validates whether the value of the specified attribute is available in a
|
3215
|
-
# particular enumerable object.
|
3216
|
-
#
|
3217
|
-
# class Person < ActiveRecord::Base
|
3218
|
-
# validates_inclusion_of :role, in: %w( admin contributor )
|
3219
|
-
# validates_inclusion_of :age, in: 0..99
|
3220
|
-
# validates_inclusion_of :format, in: %w( jpg gif png ), message: "extension %{value} is not included in the list"
|
3221
|
-
# validates_inclusion_of :states, in: ->(person) { STATES[person.country] }
|
3222
|
-
# validates_inclusion_of :karma, in: :available_karmas
|
3223
|
-
# end
|
3224
|
-
#
|
3225
|
-
# Configuration options:
|
3226
|
-
# * <tt>:in</tt> - An enumerable object of available items. This can be
|
3227
|
-
# supplied as a proc, lambda or symbol which returns an enumerable. If the
|
3228
|
-
# enumerable is a numerical, time or datetime range the test is performed
|
3229
|
-
# with <tt>Range#cover?</tt>, otherwise with <tt>include?</tt>. When using
|
3230
|
-
# a proc or lambda the instance under validation is passed as an argument.
|
3231
|
-
# * <tt>:within</tt> - A synonym(or alias) for <tt>:in</tt>
|
3232
|
-
# * <tt>:message</tt> - Specifies a custom error message (default is: "is
|
3233
|
-
# not included in the list").
|
3234
|
-
#
|
3235
|
-
# There is also a list of default options supported by every validator:
|
3236
|
-
# +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+.
|
3237
|
-
# See <tt>ActiveModel::Validations#validates</tt> for more information
|
3238
|
-
def validates_inclusion_of: (*untyped attr_names) -> untyped
|
3239
|
-
end
|
3240
|
-
end
|
3241
|
-
end
|
3242
|
-
|
3243
|
-
module ActiveModel
|
3244
|
-
module Validations
|
3245
|
-
class LengthValidator < EachValidator
|
3246
|
-
# :nodoc:
|
3247
|
-
MESSAGES: untyped
|
3248
|
-
|
3249
|
-
CHECKS: untyped
|
3250
|
-
|
3251
|
-
RESERVED_OPTIONS: ::Array[untyped]
|
3252
|
-
|
3253
|
-
def initialize: (untyped options) -> untyped
|
3254
|
-
|
3255
|
-
def check_validity!: () -> untyped
|
3256
|
-
|
3257
|
-
def validate_each: (untyped record, untyped attribute, untyped value) -> untyped
|
3258
|
-
|
3259
|
-
def skip_nil_check?: (untyped key) -> untyped
|
3260
|
-
end
|
3261
|
-
|
3262
|
-
module HelperMethods
|
3263
|
-
# Validates that the specified attributes match the length restrictions
|
3264
|
-
# supplied. Only one constraint option can be used at a time apart from
|
3265
|
-
# +:minimum+ and +:maximum+ that can be combined together:
|
3266
|
-
#
|
3267
|
-
# class Person < ActiveRecord::Base
|
3268
|
-
# validates_length_of :first_name, maximum: 30
|
3269
|
-
# validates_length_of :last_name, maximum: 30, message: "less than 30 if you don't mind"
|
3270
|
-
# validates_length_of :fax, in: 7..32, allow_nil: true
|
3271
|
-
# validates_length_of :phone, in: 7..32, allow_blank: true
|
3272
|
-
# validates_length_of :user_name, within: 6..20, too_long: 'pick a shorter name', too_short: 'pick a longer name'
|
3273
|
-
# validates_length_of :zip_code, minimum: 5, too_short: 'please enter at least 5 characters'
|
3274
|
-
# validates_length_of :smurf_leader, is: 4, message: "papa is spelled with 4 characters... don't play me."
|
3275
|
-
# validates_length_of :words_in_essay, minimum: 100, too_short: 'Your essay must be at least 100 words.'
|
3276
|
-
#
|
3277
|
-
# private
|
3278
|
-
#
|
3279
|
-
# def words_in_essay
|
3280
|
-
# essay.scan(/\w+/)
|
3281
|
-
# end
|
3282
|
-
# end
|
3283
|
-
#
|
3284
|
-
# Constraint options:
|
3285
|
-
#
|
3286
|
-
# * <tt>:minimum</tt> - The minimum size of the attribute.
|
3287
|
-
# * <tt>:maximum</tt> - The maximum size of the attribute. Allows +nil+ by
|
3288
|
-
# default if not used with +:minimum+.
|
3289
|
-
# * <tt>:is</tt> - The exact size of the attribute.
|
3290
|
-
# * <tt>:within</tt> - A range specifying the minimum and maximum size of
|
3291
|
-
# the attribute.
|
3292
|
-
# * <tt>:in</tt> - A synonym (or alias) for <tt>:within</tt>.
|
3293
|
-
#
|
3294
|
-
# Other options:
|
3295
|
-
#
|
3296
|
-
# * <tt>:allow_nil</tt> - Attribute may be +nil+; skip validation.
|
3297
|
-
# * <tt>:allow_blank</tt> - Attribute may be blank; skip validation.
|
3298
|
-
# * <tt>:too_long</tt> - The error message if the attribute goes over the
|
3299
|
-
# maximum (default is: "is too long (maximum is %{count} characters)").
|
3300
|
-
# * <tt>:too_short</tt> - The error message if the attribute goes under the
|
3301
|
-
# minimum (default is: "is too short (minimum is %{count} characters)").
|
3302
|
-
# * <tt>:wrong_length</tt> - The error message if using the <tt>:is</tt>
|
3303
|
-
# method and the attribute is the wrong size (default is: "is the wrong
|
3304
|
-
# length (should be %{count} characters)").
|
3305
|
-
# * <tt>:message</tt> - The error message to use for a <tt>:minimum</tt>,
|
3306
|
-
# <tt>:maximum</tt>, or <tt>:is</tt> violation. An alias of the appropriate
|
3307
|
-
# <tt>too_long</tt>/<tt>too_short</tt>/<tt>wrong_length</tt> message.
|
3308
|
-
#
|
3309
|
-
# There is also a list of default options supported by every validator:
|
3310
|
-
# +:if+, +:unless+, +:on+ and +:strict+.
|
3311
|
-
# See <tt>ActiveModel::Validations#validates</tt> for more information
|
3312
|
-
def validates_length_of: (*untyped attr_names) -> untyped
|
3313
|
-
|
3314
|
-
alias validates_size_of validates_length_of
|
3315
|
-
end
|
3316
|
-
end
|
3317
|
-
end
|
3318
|
-
|
3319
|
-
module ActiveModel
|
3320
|
-
module Validations
|
3321
|
-
class NumericalityValidator < EachValidator
|
3322
|
-
# :nodoc:
|
3323
|
-
CHECKS: untyped
|
3324
|
-
|
3325
|
-
RESERVED_OPTIONS: untyped
|
3326
|
-
|
3327
|
-
INTEGER_REGEX: untyped
|
3328
|
-
|
3329
|
-
HEXADECIMAL_REGEX: untyped
|
3330
|
-
|
3331
|
-
def check_validity!: () -> untyped
|
3332
|
-
|
3333
|
-
def validate_each: (untyped record, untyped attr_name, untyped value) -> (nil | untyped)
|
3334
|
-
|
3335
|
-
def is_number?: (untyped raw_value) -> untyped
|
3336
|
-
|
3337
|
-
def parse_as_number: (untyped raw_value) -> untyped
|
3338
|
-
|
3339
|
-
def is_integer?: (untyped raw_value) -> untyped
|
3340
|
-
|
3341
|
-
def is_hexadecimal_literal?: (untyped raw_value) -> untyped
|
3342
|
-
|
3343
|
-
def filtered_options: (untyped value) -> untyped
|
3344
|
-
|
3345
|
-
def allow_only_integer?: (untyped record) -> untyped
|
3346
|
-
|
3347
|
-
def record_attribute_changed_in_place?: (untyped record, untyped attr_name) -> untyped
|
3348
|
-
end
|
3349
|
-
|
3350
|
-
module HelperMethods
|
3351
|
-
# Validates whether the value of the specified attribute is numeric by
|
3352
|
-
# trying to convert it to a float with Kernel.Float (if <tt>only_integer</tt>
|
3353
|
-
# is +false+) or applying it to the regular expression <tt>/\A[\+\-]?\d+\z/</tt>
|
3354
|
-
# (if <tt>only_integer</tt> is set to +true+).
|
3355
|
-
#
|
3356
|
-
# class Person < ActiveRecord::Base
|
3357
|
-
# validates_numericality_of :value, on: :create
|
3358
|
-
# end
|
3359
|
-
#
|
3360
|
-
# Configuration options:
|
3361
|
-
# * <tt>:message</tt> - A custom error message (default is: "is not a number").
|
3362
|
-
# * <tt>:only_integer</tt> - Specifies whether the value has to be an
|
3363
|
-
# integer, e.g. an integral value (default is +false+).
|
3364
|
-
# * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+ (default is
|
3365
|
-
# +false+). Notice that for Integer and Float columns empty strings are
|
3366
|
-
# converted to +nil+.
|
3367
|
-
# * <tt>:greater_than</tt> - Specifies the value must be greater than the
|
3368
|
-
# supplied value.
|
3369
|
-
# * <tt>:greater_than_or_equal_to</tt> - Specifies the value must be
|
3370
|
-
# greater than or equal the supplied value.
|
3371
|
-
# * <tt>:equal_to</tt> - Specifies the value must be equal to the supplied
|
3372
|
-
# value.
|
3373
|
-
# * <tt>:less_than</tt> - Specifies the value must be less than the
|
3374
|
-
# supplied value.
|
3375
|
-
# * <tt>:less_than_or_equal_to</tt> - Specifies the value must be less
|
3376
|
-
# than or equal the supplied value.
|
3377
|
-
# * <tt>:other_than</tt> - Specifies the value must be other than the
|
3378
|
-
# supplied value.
|
3379
|
-
# * <tt>:odd</tt> - Specifies the value must be an odd number.
|
3380
|
-
# * <tt>:even</tt> - Specifies the value must be an even number.
|
3381
|
-
#
|
3382
|
-
# There is also a list of default options supported by every validator:
|
3383
|
-
# +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+ .
|
3384
|
-
# See <tt>ActiveModel::Validations#validates</tt> for more information
|
3385
|
-
#
|
3386
|
-
# The following checks can also be supplied with a proc or a symbol which
|
3387
|
-
# corresponds to a method:
|
3388
|
-
#
|
3389
|
-
# * <tt>:greater_than</tt>
|
3390
|
-
# * <tt>:greater_than_or_equal_to</tt>
|
3391
|
-
# * <tt>:equal_to</tt>
|
3392
|
-
# * <tt>:less_than</tt>
|
3393
|
-
# * <tt>:less_than_or_equal_to</tt>
|
3394
|
-
# * <tt>:only_integer</tt>
|
3395
|
-
#
|
3396
|
-
# For example:
|
3397
|
-
#
|
3398
|
-
# class Person < ActiveRecord::Base
|
3399
|
-
# validates_numericality_of :width, less_than: ->(person) { person.height }
|
3400
|
-
# validates_numericality_of :width, greater_than: :minimum_weight
|
3401
|
-
# end
|
3402
|
-
def validates_numericality_of: (*untyped attr_names) -> untyped
|
3403
|
-
end
|
3404
|
-
end
|
3405
|
-
end
|
3406
|
-
|
3407
|
-
module ActiveModel
|
3408
|
-
module Validations
|
3409
|
-
class PresenceValidator < EachValidator
|
3410
|
-
# :nodoc:
|
3411
|
-
def validate_each: (untyped record, untyped attr_name, untyped value) -> untyped
|
3412
|
-
end
|
3413
|
-
|
3414
|
-
module HelperMethods
|
3415
|
-
# Validates that the specified attributes are not blank (as defined by
|
3416
|
-
# Object#blank?). Happens by default on save.
|
3417
|
-
#
|
3418
|
-
# class Person < ActiveRecord::Base
|
3419
|
-
# validates_presence_of :first_name
|
3420
|
-
# end
|
3421
|
-
#
|
3422
|
-
# The first_name attribute must be in the object and it cannot be blank.
|
3423
|
-
#
|
3424
|
-
# If you want to validate the presence of a boolean field (where the real
|
3425
|
-
# values are +true+ and +false+), you will want to use
|
3426
|
-
# <tt>validates_inclusion_of :field_name, in: [true, false]</tt>.
|
3427
|
-
#
|
3428
|
-
# This is due to the way Object#blank? handles boolean values:
|
3429
|
-
# <tt>false.blank? # => true</tt>.
|
3430
|
-
#
|
3431
|
-
# Configuration options:
|
3432
|
-
# * <tt>:message</tt> - A custom error message (default is: "can't be blank").
|
3433
|
-
#
|
3434
|
-
# There is also a list of default options supported by every validator:
|
3435
|
-
# +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+.
|
3436
|
-
# See <tt>ActiveModel::Validations#validates</tt> for more information
|
3437
|
-
def validates_presence_of: (*untyped attr_names) -> untyped
|
3438
|
-
end
|
3439
|
-
end
|
3440
|
-
end
|
3441
|
-
|
3442
|
-
module ActiveModel
|
3443
|
-
module Validations
|
3444
|
-
module ClassMethods
|
3445
|
-
# This method is a shortcut to all default validators and any custom
|
3446
|
-
# validator classes ending in 'Validator'. Note that Rails default
|
3447
|
-
# validators can be overridden inside specific classes by creating
|
3448
|
-
# custom validator classes in their place such as PresenceValidator.
|
3449
|
-
#
|
3450
|
-
# Examples of using the default rails validators:
|
3451
|
-
#
|
3452
|
-
# validates :terms, acceptance: true
|
3453
|
-
# validates :password, confirmation: true
|
3454
|
-
# validates :username, exclusion: { in: %w(admin superuser) }
|
3455
|
-
# validates :email, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, on: :create }
|
3456
|
-
# validates :age, inclusion: { in: 0..9 }
|
3457
|
-
# validates :first_name, length: { maximum: 30 }
|
3458
|
-
# validates :age, numericality: true
|
3459
|
-
# validates :username, presence: true
|
3460
|
-
#
|
3461
|
-
# The power of the +validates+ method comes when using custom validators
|
3462
|
-
# and default validators in one call for a given attribute.
|
3463
|
-
#
|
3464
|
-
# class EmailValidator < ActiveModel::EachValidator
|
3465
|
-
# def validate_each(record, attribute, value)
|
3466
|
-
# record.errors.add attribute, (options[:message] || "is not an email") unless
|
3467
|
-
# value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
|
3468
|
-
# end
|
3469
|
-
# end
|
3470
|
-
#
|
3471
|
-
# class Person
|
3472
|
-
# include ActiveModel::Validations
|
3473
|
-
# attr_accessor :name, :email
|
3474
|
-
#
|
3475
|
-
# validates :name, presence: true, length: { maximum: 100 }
|
3476
|
-
# validates :email, presence: true, email: true
|
3477
|
-
# end
|
3478
|
-
#
|
3479
|
-
# Validator classes may also exist within the class being validated
|
3480
|
-
# allowing custom modules of validators to be included as needed.
|
3481
|
-
#
|
3482
|
-
# class Film
|
3483
|
-
# include ActiveModel::Validations
|
3484
|
-
#
|
3485
|
-
# class TitleValidator < ActiveModel::EachValidator
|
3486
|
-
# def validate_each(record, attribute, value)
|
3487
|
-
# record.errors.add attribute, "must start with 'the'" unless value =~ /\Athe/i
|
3488
|
-
# end
|
3489
|
-
# end
|
3490
|
-
#
|
3491
|
-
# validates :name, title: true
|
3492
|
-
# end
|
3493
|
-
#
|
3494
|
-
# Additionally validator classes may be in another namespace and still
|
3495
|
-
# used within any class.
|
3496
|
-
#
|
3497
|
-
# validates :name, :'film/title' => true
|
3498
|
-
#
|
3499
|
-
# The validators hash can also handle regular expressions, ranges, arrays
|
3500
|
-
# and strings in shortcut form.
|
3501
|
-
#
|
3502
|
-
# validates :email, format: /@/
|
3503
|
-
# validates :role, inclusion: %(admin contributor)
|
3504
|
-
# validates :password, length: 6..20
|
3505
|
-
#
|
3506
|
-
# When using shortcut form, ranges and arrays are passed to your
|
3507
|
-
# validator's initializer as <tt>options[:in]</tt> while other types
|
3508
|
-
# including regular expressions and strings are passed as <tt>options[:with]</tt>.
|
3509
|
-
#
|
3510
|
-
# There is also a list of options that could be used along with validators:
|
3511
|
-
#
|
3512
|
-
# * <tt>:on</tt> - Specifies the contexts where this validation is active.
|
3513
|
-
# Runs in all validation contexts by default +nil+. You can pass a symbol
|
3514
|
-
# or an array of symbols. (e.g. <tt>on: :create</tt> or
|
3515
|
-
# <tt>on: :custom_validation_context</tt> or
|
3516
|
-
# <tt>on: [:create, :custom_validation_context]</tt>)
|
3517
|
-
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine
|
3518
|
-
# if the validation should occur (e.g. <tt>if: :allow_validation</tt>,
|
3519
|
-
# or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method,
|
3520
|
-
# proc or string should return or evaluate to a +true+ or +false+ value.
|
3521
|
-
# * <tt>:unless</tt> - Specifies a method, proc or string to call to determine
|
3522
|
-
# if the validation should not occur (e.g. <tt>unless: :skip_validation</tt>,
|
3523
|
-
# or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>). The
|
3524
|
-
# method, proc or string should return or evaluate to a +true+ or
|
3525
|
-
# +false+ value.
|
3526
|
-
# * <tt>:allow_nil</tt> - Skip validation if the attribute is +nil+.
|
3527
|
-
# * <tt>:allow_blank</tt> - Skip validation if the attribute is blank.
|
3528
|
-
# * <tt>:strict</tt> - If the <tt>:strict</tt> option is set to true
|
3529
|
-
# will raise ActiveModel::StrictValidationFailed instead of adding the error.
|
3530
|
-
# <tt>:strict</tt> option can also be set to any other exception.
|
3531
|
-
#
|
3532
|
-
# Example:
|
3533
|
-
#
|
3534
|
-
# validates :password, presence: true, confirmation: true, if: :password_required?
|
3535
|
-
# validates :token, length: 24, strict: TokenLengthException
|
3536
|
-
#
|
3537
|
-
#
|
3538
|
-
# Finally, the options +:if+, +:unless+, +:on+, +:allow_blank+, +:allow_nil+, +:strict+
|
3539
|
-
# and +:message+ can be given to one specific validator, as a hash:
|
3540
|
-
#
|
3541
|
-
# validates :password, presence: { if: :password_required?, message: 'is forgotten.' }, confirmation: true
|
3542
|
-
def validates: (*untyped attributes) -> untyped
|
3543
|
-
|
3544
|
-
# This method is used to define validations that cannot be corrected by end
|
3545
|
-
# users and are considered exceptional. So each validator defined with bang
|
3546
|
-
# or <tt>:strict</tt> option set to <tt>true</tt> will always raise
|
3547
|
-
# <tt>ActiveModel::StrictValidationFailed</tt> instead of adding error
|
3548
|
-
# when validation fails. See <tt>validates</tt> for more information about
|
3549
|
-
# the validation itself.
|
3550
|
-
#
|
3551
|
-
# class Person
|
3552
|
-
# include ActiveModel::Validations
|
3553
|
-
#
|
3554
|
-
# attr_accessor :name
|
3555
|
-
# validates! :name, presence: true
|
3556
|
-
# end
|
3557
|
-
#
|
3558
|
-
# person = Person.new
|
3559
|
-
# person.name = ''
|
3560
|
-
# person.valid?
|
3561
|
-
# # => ActiveModel::StrictValidationFailed: Name can't be blank
|
3562
|
-
def validates!: (*untyped attributes) -> untyped
|
3563
|
-
|
3564
|
-
# When creating custom validators, it might be useful to be able to specify
|
3565
|
-
# additional default keys. This can be done by overwriting this method.
|
3566
|
-
def _validates_default_keys: () -> ::Array[:if | :unless | :on | :allow_blank | :allow_nil | :strict]
|
3567
|
-
|
3568
|
-
def _parse_validates_options: (untyped options) -> untyped
|
3569
|
-
end
|
3570
|
-
end
|
3571
|
-
end
|
3572
|
-
|
3573
|
-
module ActiveModel
|
3574
|
-
module Validations
|
3575
|
-
class WithValidator < EachValidator
|
3576
|
-
# :nodoc:
|
3577
|
-
def validate_each: (untyped record, untyped attr, untyped val) -> untyped
|
3578
|
-
end
|
3579
|
-
|
3580
|
-
module ClassMethods
|
3581
|
-
# Passes the record off to the class or classes specified and allows them
|
3582
|
-
# to add errors based on more complex conditions.
|
3583
|
-
#
|
3584
|
-
# class Person
|
3585
|
-
# include ActiveModel::Validations
|
3586
|
-
# validates_with MyValidator
|
3587
|
-
# end
|
3588
|
-
#
|
3589
|
-
# class MyValidator < ActiveModel::Validator
|
3590
|
-
# def validate(record)
|
3591
|
-
# if some_complex_logic
|
3592
|
-
# record.errors.add :base, 'This record is invalid'
|
3593
|
-
# end
|
3594
|
-
# end
|
3595
|
-
#
|
3596
|
-
# private
|
3597
|
-
# def some_complex_logic
|
3598
|
-
# # ...
|
3599
|
-
# end
|
3600
|
-
# end
|
3601
|
-
#
|
3602
|
-
# You may also pass it multiple classes, like so:
|
3603
|
-
#
|
3604
|
-
# class Person
|
3605
|
-
# include ActiveModel::Validations
|
3606
|
-
# validates_with MyValidator, MyOtherValidator, on: :create
|
3607
|
-
# end
|
3608
|
-
#
|
3609
|
-
# Configuration options:
|
3610
|
-
# * <tt>:on</tt> - Specifies the contexts where this validation is active.
|
3611
|
-
# Runs in all validation contexts by default +nil+. You can pass a symbol
|
3612
|
-
# or an array of symbols. (e.g. <tt>on: :create</tt> or
|
3613
|
-
# <tt>on: :custom_validation_context</tt> or
|
3614
|
-
# <tt>on: [:create, :custom_validation_context]</tt>)
|
3615
|
-
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine
|
3616
|
-
# if the validation should occur (e.g. <tt>if: :allow_validation</tt>,
|
3617
|
-
# or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>).
|
3618
|
-
# The method, proc or string should return or evaluate to a +true+ or
|
3619
|
-
# +false+ value.
|
3620
|
-
# * <tt>:unless</tt> - Specifies a method, proc or string to call to
|
3621
|
-
# determine if the validation should not occur
|
3622
|
-
# (e.g. <tt>unless: :skip_validation</tt>, or
|
3623
|
-
# <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>).
|
3624
|
-
# The method, proc or string should return or evaluate to a +true+ or
|
3625
|
-
# +false+ value.
|
3626
|
-
# * <tt>:strict</tt> - Specifies whether validation should be strict.
|
3627
|
-
# See <tt>ActiveModel::Validations#validates!</tt> for more information.
|
3628
|
-
#
|
3629
|
-
# If you pass any additional configuration options, they will be passed
|
3630
|
-
# to the class and available as +options+:
|
3631
|
-
#
|
3632
|
-
# class Person
|
3633
|
-
# include ActiveModel::Validations
|
3634
|
-
# validates_with MyValidator, my_custom_key: 'my custom value'
|
3635
|
-
# end
|
3636
|
-
#
|
3637
|
-
# class MyValidator < ActiveModel::Validator
|
3638
|
-
# def validate(record)
|
3639
|
-
# options[:my_custom_key] # => "my custom value"
|
3640
|
-
# end
|
3641
|
-
# end
|
3642
|
-
def validates_with: (*untyped args) { () -> untyped } -> untyped
|
3643
|
-
end
|
3644
|
-
|
3645
|
-
# Passes the record off to the class or classes specified and allows them
|
3646
|
-
# to add errors based on more complex conditions.
|
3647
|
-
#
|
3648
|
-
# class Person
|
3649
|
-
# include ActiveModel::Validations
|
3650
|
-
#
|
3651
|
-
# validate :instance_validations
|
3652
|
-
#
|
3653
|
-
# def instance_validations
|
3654
|
-
# validates_with MyValidator
|
3655
|
-
# end
|
3656
|
-
# end
|
3657
|
-
#
|
3658
|
-
# Please consult the class method documentation for more information on
|
3659
|
-
# creating your own validator.
|
3660
|
-
#
|
3661
|
-
# You may also pass it multiple classes, like so:
|
3662
|
-
#
|
3663
|
-
# class Person
|
3664
|
-
# include ActiveModel::Validations
|
3665
|
-
#
|
3666
|
-
# validate :instance_validations, on: :create
|
3667
|
-
#
|
3668
|
-
# def instance_validations
|
3669
|
-
# validates_with MyValidator, MyOtherValidator
|
3670
|
-
# end
|
3671
|
-
# end
|
3672
|
-
#
|
3673
|
-
# Standard configuration options (<tt>:on</tt>, <tt>:if</tt> and
|
3674
|
-
# <tt>:unless</tt>), which are available on the class version of
|
3675
|
-
# +validates_with+, should instead be placed on the +validates+ method
|
3676
|
-
# as these are applied and tested in the callback.
|
3677
|
-
#
|
3678
|
-
# If you pass any additional configuration options, they will be passed
|
3679
|
-
# to the class and available as +options+, please refer to the
|
3680
|
-
# class version of this method for more information.
|
3681
|
-
def validates_with: (*untyped args) { () -> untyped } -> untyped
|
3682
|
-
end
|
3683
|
-
end
|
3684
|
-
|
3685
|
-
module ActiveModel
|
3686
|
-
# == Active \Model \Validations
|
3687
|
-
#
|
3688
|
-
# Provides a full validation framework to your objects.
|
3689
|
-
#
|
3690
|
-
# A minimal implementation could be:
|
3691
|
-
#
|
3692
|
-
# class Person
|
3693
|
-
# include ActiveModel::Validations
|
3694
|
-
#
|
3695
|
-
# attr_accessor :first_name, :last_name
|
3696
|
-
#
|
3697
|
-
# validates_each :first_name, :last_name do |record, attr, value|
|
3698
|
-
# record.errors.add attr, 'starts with z.' if value.to_s[0] == ?z
|
3699
|
-
# end
|
3700
|
-
# end
|
3701
|
-
#
|
3702
|
-
# Which provides you with the full standard validation stack that you
|
3703
|
-
# know from Active Record:
|
3704
|
-
#
|
3705
|
-
# person = Person.new
|
3706
|
-
# person.valid? # => true
|
3707
|
-
# person.invalid? # => false
|
3708
|
-
#
|
3709
|
-
# person.first_name = 'zoolander'
|
3710
|
-
# person.valid? # => false
|
3711
|
-
# person.invalid? # => true
|
3712
|
-
# person.errors.messages # => {first_name:["starts with z."]}
|
3713
|
-
#
|
3714
|
-
# Note that <tt>ActiveModel::Validations</tt> automatically adds an +errors+
|
3715
|
-
# method to your instances initialized with a new <tt>ActiveModel::Errors</tt>
|
3716
|
-
# object, so there is no need for you to do this manually.
|
3717
|
-
module Validations
|
3718
|
-
extend ActiveSupport::Concern
|
3719
|
-
|
3720
|
-
extend ActiveModel::Naming
|
3721
|
-
|
3722
|
-
extend ActiveModel::Callbacks
|
3723
|
-
|
3724
|
-
extend ActiveModel::Translation
|
3725
|
-
|
3726
|
-
extend HelperMethods
|
3727
|
-
|
3728
|
-
include HelperMethods
|
3729
|
-
|
3730
|
-
attr_accessor validation_context: untyped
|
3731
|
-
|
3732
|
-
module ClassMethods
|
3733
|
-
# Validates each attribute against a block.
|
3734
|
-
#
|
3735
|
-
# class Person
|
3736
|
-
# include ActiveModel::Validations
|
3737
|
-
#
|
3738
|
-
# attr_accessor :first_name, :last_name
|
3739
|
-
#
|
3740
|
-
# validates_each :first_name, :last_name, allow_blank: true do |record, attr, value|
|
3741
|
-
# record.errors.add attr, 'starts with z.' if value.to_s[0] == ?z
|
3742
|
-
# end
|
3743
|
-
# end
|
3744
|
-
#
|
3745
|
-
# Options:
|
3746
|
-
# * <tt>:on</tt> - Specifies the contexts where this validation is active.
|
3747
|
-
# Runs in all validation contexts by default +nil+. You can pass a symbol
|
3748
|
-
# or an array of symbols. (e.g. <tt>on: :create</tt> or
|
3749
|
-
# <tt>on: :custom_validation_context</tt> or
|
3750
|
-
# <tt>on: [:create, :custom_validation_context]</tt>)
|
3751
|
-
# * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+.
|
3752
|
-
# * <tt>:allow_blank</tt> - Skip validation if attribute is blank.
|
3753
|
-
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine
|
3754
|
-
# if the validation should occur (e.g. <tt>if: :allow_validation</tt>,
|
3755
|
-
# or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method,
|
3756
|
-
# proc or string should return or evaluate to a +true+ or +false+ value.
|
3757
|
-
# * <tt>:unless</tt> - Specifies a method, proc or string to call to
|
3758
|
-
# determine if the validation should not occur (e.g. <tt>unless: :skip_validation</tt>,
|
3759
|
-
# or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>). The
|
3760
|
-
# method, proc or string should return or evaluate to a +true+ or +false+
|
3761
|
-
# value.
|
3762
|
-
def validates_each: (*untyped attr_names) { () -> untyped } -> untyped
|
3763
|
-
|
3764
|
-
VALID_OPTIONS_FOR_VALIDATE: untyped
|
3765
|
-
|
3766
|
-
# Adds a validation method or block to the class. This is useful when
|
3767
|
-
# overriding the +validate+ instance method becomes too unwieldy and
|
3768
|
-
# you're looking for more descriptive declaration of your validations.
|
3769
|
-
#
|
3770
|
-
# This can be done with a symbol pointing to a method:
|
3771
|
-
#
|
3772
|
-
# class Comment
|
3773
|
-
# include ActiveModel::Validations
|
3774
|
-
#
|
3775
|
-
# validate :must_be_friends
|
3776
|
-
#
|
3777
|
-
# def must_be_friends
|
3778
|
-
# errors.add(:base, 'Must be friends to leave a comment') unless commenter.friend_of?(commentee)
|
3779
|
-
# end
|
3780
|
-
# end
|
3781
|
-
#
|
3782
|
-
# With a block which is passed with the current record to be validated:
|
3783
|
-
#
|
3784
|
-
# class Comment
|
3785
|
-
# include ActiveModel::Validations
|
3786
|
-
#
|
3787
|
-
# validate do |comment|
|
3788
|
-
# comment.must_be_friends
|
3789
|
-
# end
|
3790
|
-
#
|
3791
|
-
# def must_be_friends
|
3792
|
-
# errors.add(:base, 'Must be friends to leave a comment') unless commenter.friend_of?(commentee)
|
3793
|
-
# end
|
3794
|
-
# end
|
3795
|
-
#
|
3796
|
-
# Or with a block where self points to the current record to be validated:
|
3797
|
-
#
|
3798
|
-
# class Comment
|
3799
|
-
# include ActiveModel::Validations
|
3800
|
-
#
|
3801
|
-
# validate do
|
3802
|
-
# errors.add(:base, 'Must be friends to leave a comment') unless commenter.friend_of?(commentee)
|
3803
|
-
# end
|
3804
|
-
# end
|
3805
|
-
#
|
3806
|
-
# Note that the return value of validation methods is not relevant.
|
3807
|
-
# It's not possible to halt the validate callback chain.
|
3808
|
-
#
|
3809
|
-
# Options:
|
3810
|
-
# * <tt>:on</tt> - Specifies the contexts where this validation is active.
|
3811
|
-
# Runs in all validation contexts by default +nil+. You can pass a symbol
|
3812
|
-
# or an array of symbols. (e.g. <tt>on: :create</tt> or
|
3813
|
-
# <tt>on: :custom_validation_context</tt> or
|
3814
|
-
# <tt>on: [:create, :custom_validation_context]</tt>)
|
3815
|
-
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine
|
3816
|
-
# if the validation should occur (e.g. <tt>if: :allow_validation</tt>,
|
3817
|
-
# or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method,
|
3818
|
-
# proc or string should return or evaluate to a +true+ or +false+ value.
|
3819
|
-
# * <tt>:unless</tt> - Specifies a method, proc or string to call to
|
3820
|
-
# determine if the validation should not occur (e.g. <tt>unless: :skip_validation</tt>,
|
3821
|
-
# or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>). The
|
3822
|
-
# method, proc or string should return or evaluate to a +true+ or +false+
|
3823
|
-
# value.
|
3824
|
-
#
|
3825
|
-
# NOTE: Calling +validate+ multiple times on the same method will overwrite previous definitions.
|
3826
|
-
#
|
3827
|
-
def validate: (*untyped args) { () -> untyped } -> untyped
|
3828
|
-
|
3829
|
-
# List all validators that are being used to validate the model using
|
3830
|
-
# +validates_with+ method.
|
3831
|
-
#
|
3832
|
-
# class Person
|
3833
|
-
# include ActiveModel::Validations
|
3834
|
-
#
|
3835
|
-
# validates_with MyValidator
|
3836
|
-
# validates_with OtherValidator, on: :create
|
3837
|
-
# validates_with StrictValidator, strict: true
|
3838
|
-
# end
|
3839
|
-
#
|
3840
|
-
# Person.validators
|
3841
|
-
# # => [
|
3842
|
-
# # #<MyValidator:0x007fbff403e808 @options={}>,
|
3843
|
-
# # #<OtherValidator:0x007fbff403d930 @options={on: :create}>,
|
3844
|
-
# # #<StrictValidator:0x007fbff3204a30 @options={strict:true}>
|
3845
|
-
# # ]
|
3846
|
-
def validators: () -> untyped
|
3847
|
-
|
3848
|
-
# Clears all of the validators and validations.
|
3849
|
-
#
|
3850
|
-
# Note that this will clear anything that is being used to validate
|
3851
|
-
# the model for both the +validates_with+ and +validate+ methods.
|
3852
|
-
# It clears the validators that are created with an invocation of
|
3853
|
-
# +validates_with+ and the callbacks that are set by an invocation
|
3854
|
-
# of +validate+.
|
3855
|
-
#
|
3856
|
-
# class Person
|
3857
|
-
# include ActiveModel::Validations
|
3858
|
-
#
|
3859
|
-
# validates_with MyValidator
|
3860
|
-
# validates_with OtherValidator, on: :create
|
3861
|
-
# validates_with StrictValidator, strict: true
|
3862
|
-
# validate :cannot_be_robot
|
3863
|
-
#
|
3864
|
-
# def cannot_be_robot
|
3865
|
-
# errors.add(:base, 'A person cannot be a robot') if person_is_robot
|
3866
|
-
# end
|
3867
|
-
# end
|
3868
|
-
#
|
3869
|
-
# Person.validators
|
3870
|
-
# # => [
|
3871
|
-
# # #<MyValidator:0x007fbff403e808 @options={}>,
|
3872
|
-
# # #<OtherValidator:0x007fbff403d930 @options={on: :create}>,
|
3873
|
-
# # #<StrictValidator:0x007fbff3204a30 @options={strict:true}>
|
3874
|
-
# # ]
|
3875
|
-
#
|
3876
|
-
# If one runs <tt>Person.clear_validators!</tt> and then checks to see what
|
3877
|
-
# validators this class has, you would obtain:
|
3878
|
-
#
|
3879
|
-
# Person.validators # => []
|
3880
|
-
#
|
3881
|
-
# Also, the callback set by <tt>validate :cannot_be_robot</tt> will be erased
|
3882
|
-
# so that:
|
3883
|
-
#
|
3884
|
-
# Person._validate_callbacks.empty? # => true
|
3885
|
-
#
|
3886
|
-
def clear_validators!: () -> untyped
|
3887
|
-
|
3888
|
-
# List all validators that are being used to validate a specific attribute.
|
3889
|
-
#
|
3890
|
-
# class Person
|
3891
|
-
# include ActiveModel::Validations
|
3892
|
-
#
|
3893
|
-
# attr_accessor :name , :age
|
3894
|
-
#
|
3895
|
-
# validates_presence_of :name
|
3896
|
-
# validates_inclusion_of :age, in: 0..99
|
3897
|
-
# end
|
3898
|
-
#
|
3899
|
-
# Person.validators_on(:name)
|
3900
|
-
# # => [
|
3901
|
-
# # #<ActiveModel::Validations::PresenceValidator:0x007fe604914e60 @attributes=[:name], @options={}>,
|
3902
|
-
# # ]
|
3903
|
-
def validators_on: (*untyped attributes) -> untyped
|
3904
|
-
|
3905
|
-
# Returns +true+ if +attribute+ is an attribute method, +false+ otherwise.
|
3906
|
-
#
|
3907
|
-
# class Person
|
3908
|
-
# include ActiveModel::Validations
|
3909
|
-
#
|
3910
|
-
# attr_accessor :name
|
3911
|
-
# end
|
3912
|
-
#
|
3913
|
-
# User.attribute_method?(:name) # => true
|
3914
|
-
# User.attribute_method?(:age) # => false
|
3915
|
-
def attribute_method?: (untyped attribute) -> untyped
|
3916
|
-
|
3917
|
-
def inherited: (untyped base) -> untyped
|
3918
|
-
end
|
3919
|
-
|
3920
|
-
def initialize_dup: (untyped other) -> untyped
|
3921
|
-
|
3922
|
-
# Returns the +Errors+ object that holds all information about attribute
|
3923
|
-
# error messages.
|
3924
|
-
#
|
3925
|
-
# class Person
|
3926
|
-
# include ActiveModel::Validations
|
3927
|
-
#
|
3928
|
-
# attr_accessor :name
|
3929
|
-
# validates_presence_of :name
|
3930
|
-
# end
|
3931
|
-
#
|
3932
|
-
# person = Person.new
|
3933
|
-
# person.valid? # => false
|
3934
|
-
# person.errors # => #<ActiveModel::Errors:0x007fe603816640 @messages={name:["can't be blank"]}>
|
3935
|
-
def errors: () -> untyped
|
3936
|
-
|
3937
|
-
# Runs all the specified validations and returns +true+ if no errors were
|
3938
|
-
# added otherwise +false+.
|
3939
|
-
#
|
3940
|
-
# class Person
|
3941
|
-
# include ActiveModel::Validations
|
3942
|
-
#
|
3943
|
-
# attr_accessor :name
|
3944
|
-
# validates_presence_of :name
|
3945
|
-
# end
|
3946
|
-
#
|
3947
|
-
# person = Person.new
|
3948
|
-
# person.name = ''
|
3949
|
-
# person.valid? # => false
|
3950
|
-
# person.name = 'david'
|
3951
|
-
# person.valid? # => true
|
3952
|
-
#
|
3953
|
-
# Context can optionally be supplied to define which callbacks to test
|
3954
|
-
# against (the context is defined on the validations using <tt>:on</tt>).
|
3955
|
-
#
|
3956
|
-
# class Person
|
3957
|
-
# include ActiveModel::Validations
|
3958
|
-
#
|
3959
|
-
# attr_accessor :name
|
3960
|
-
# validates_presence_of :name, on: :new
|
3961
|
-
# end
|
3962
|
-
#
|
3963
|
-
# person = Person.new
|
3964
|
-
# person.valid? # => true
|
3965
|
-
# person.valid?(:new) # => false
|
3966
|
-
def valid?: (?untyped? context) -> untyped
|
3967
|
-
|
3968
|
-
alias validate valid?
|
3969
|
-
|
3970
|
-
# Performs the opposite of <tt>valid?</tt>. Returns +true+ if errors were
|
3971
|
-
# added, +false+ otherwise.
|
3972
|
-
#
|
3973
|
-
# class Person
|
3974
|
-
# include ActiveModel::Validations
|
3975
|
-
#
|
3976
|
-
# attr_accessor :name
|
3977
|
-
# validates_presence_of :name
|
3978
|
-
# end
|
3979
|
-
#
|
3980
|
-
# person = Person.new
|
3981
|
-
# person.name = ''
|
3982
|
-
# person.invalid? # => true
|
3983
|
-
# person.name = 'david'
|
3984
|
-
# person.invalid? # => false
|
3985
|
-
#
|
3986
|
-
# Context can optionally be supplied to define which callbacks to test
|
3987
|
-
# against (the context is defined on the validations using <tt>:on</tt>).
|
3988
|
-
#
|
3989
|
-
# class Person
|
3990
|
-
# include ActiveModel::Validations
|
3991
|
-
#
|
3992
|
-
# attr_accessor :name
|
3993
|
-
# validates_presence_of :name, on: :new
|
3994
|
-
# end
|
3995
|
-
#
|
3996
|
-
# person = Person.new
|
3997
|
-
# person.invalid? # => false
|
3998
|
-
# person.invalid?(:new) # => true
|
3999
|
-
def invalid?: (?untyped? context) -> untyped
|
4000
|
-
|
4001
|
-
# Runs all the validations within the specified context. Returns +true+ if
|
4002
|
-
# no errors are found, raises +ValidationError+ otherwise.
|
4003
|
-
#
|
4004
|
-
# Validations with no <tt>:on</tt> option will run no matter the context. Validations with
|
4005
|
-
# some <tt>:on</tt> option will only run in the specified context.
|
4006
|
-
def validate!: (?untyped? context) -> untyped
|
4007
|
-
|
4008
|
-
# Hook method defining how an attribute value should be retrieved. By default
|
4009
|
-
# this is assumed to be an instance named after the attribute. Override this
|
4010
|
-
# method in subclasses should you need to retrieve the value for a given
|
4011
|
-
# attribute differently:
|
4012
|
-
#
|
4013
|
-
# class MyClass
|
4014
|
-
# include ActiveModel::Validations
|
4015
|
-
#
|
4016
|
-
# def initialize(data = {})
|
4017
|
-
# @data = data
|
4018
|
-
# end
|
4019
|
-
#
|
4020
|
-
# def read_attribute_for_validation(key)
|
4021
|
-
# @data[key]
|
4022
|
-
# end
|
4023
|
-
# end
|
4024
|
-
alias read_attribute_for_validation send
|
4025
|
-
|
4026
|
-
def run_validations!: () -> untyped
|
4027
|
-
|
4028
|
-
def raise_validation_error: () -> untyped
|
4029
|
-
end
|
4030
|
-
|
4031
|
-
# = Active Model ValidationError
|
4032
|
-
#
|
4033
|
-
# Raised by <tt>validate!</tt> when the model is invalid. Use the
|
4034
|
-
# +model+ method to retrieve the record which did not validate.
|
4035
|
-
#
|
4036
|
-
# begin
|
4037
|
-
# complex_operation_that_internally_calls_validate!
|
4038
|
-
# rescue ActiveModel::ValidationError => invalid
|
4039
|
-
# puts invalid.model.errors
|
4040
|
-
# end
|
4041
|
-
class ValidationError < StandardError
|
4042
|
-
attr_reader model: untyped
|
4043
|
-
|
4044
|
-
def initialize: (untyped model) -> untyped
|
4045
|
-
end
|
4046
|
-
end
|
4047
|
-
|
4048
|
-
module ActiveModel
|
4049
|
-
# == Active \Model \Validator
|
4050
|
-
#
|
4051
|
-
# A simple base class that can be used along with
|
4052
|
-
# ActiveModel::Validations::ClassMethods.validates_with
|
4053
|
-
#
|
4054
|
-
# class Person
|
4055
|
-
# include ActiveModel::Validations
|
4056
|
-
# validates_with MyValidator
|
4057
|
-
# end
|
4058
|
-
#
|
4059
|
-
# class MyValidator < ActiveModel::Validator
|
4060
|
-
# def validate(record)
|
4061
|
-
# if some_complex_logic
|
4062
|
-
# record.errors.add(:base, "This record is invalid")
|
4063
|
-
# end
|
4064
|
-
# end
|
4065
|
-
#
|
4066
|
-
# private
|
4067
|
-
# def some_complex_logic
|
4068
|
-
# # ...
|
4069
|
-
# end
|
4070
|
-
# end
|
4071
|
-
#
|
4072
|
-
# Any class that inherits from ActiveModel::Validator must implement a method
|
4073
|
-
# called +validate+ which accepts a +record+.
|
4074
|
-
#
|
4075
|
-
# class Person
|
4076
|
-
# include ActiveModel::Validations
|
4077
|
-
# validates_with MyValidator
|
4078
|
-
# end
|
4079
|
-
#
|
4080
|
-
# class MyValidator < ActiveModel::Validator
|
4081
|
-
# def validate(record)
|
4082
|
-
# record # => The person instance being validated
|
4083
|
-
# options # => Any non-standard options passed to validates_with
|
4084
|
-
# end
|
4085
|
-
# end
|
4086
|
-
#
|
4087
|
-
# To cause a validation error, you must add to the +record+'s errors directly
|
4088
|
-
# from within the validators message.
|
4089
|
-
#
|
4090
|
-
# class MyValidator < ActiveModel::Validator
|
4091
|
-
# def validate(record)
|
4092
|
-
# record.errors.add :base, "This is some custom error message"
|
4093
|
-
# record.errors.add :first_name, "This is some complex validation"
|
4094
|
-
# # etc...
|
4095
|
-
# end
|
4096
|
-
# end
|
4097
|
-
#
|
4098
|
-
# To add behavior to the initialize method, use the following signature:
|
4099
|
-
#
|
4100
|
-
# class MyValidator < ActiveModel::Validator
|
4101
|
-
# def initialize(options)
|
4102
|
-
# super
|
4103
|
-
# @my_custom_field = options[:field_name] || :first_name
|
4104
|
-
# end
|
4105
|
-
# end
|
4106
|
-
#
|
4107
|
-
# Note that the validator is initialized only once for the whole application
|
4108
|
-
# life cycle, and not on each validation run.
|
4109
|
-
#
|
4110
|
-
# The easiest way to add custom validators for validating individual attributes
|
4111
|
-
# is with the convenient <tt>ActiveModel::EachValidator</tt>.
|
4112
|
-
#
|
4113
|
-
# class TitleValidator < ActiveModel::EachValidator
|
4114
|
-
# def validate_each(record, attribute, value)
|
4115
|
-
# record.errors.add attribute, 'must be Mr., Mrs., or Dr.' unless %w(Mr. Mrs. Dr.).include?(value)
|
4116
|
-
# end
|
4117
|
-
# end
|
4118
|
-
#
|
4119
|
-
# This can now be used in combination with the +validates+ method
|
4120
|
-
# (see <tt>ActiveModel::Validations::ClassMethods.validates</tt> for more on this).
|
4121
|
-
#
|
4122
|
-
# class Person
|
4123
|
-
# include ActiveModel::Validations
|
4124
|
-
# attr_accessor :title
|
4125
|
-
#
|
4126
|
-
# validates :title, presence: true, title: true
|
4127
|
-
# end
|
4128
|
-
#
|
4129
|
-
# It can be useful to access the class that is using that validator when there are prerequisites such
|
4130
|
-
# as an +attr_accessor+ being present. This class is accessible via <tt>options[:class]</tt> in the constructor.
|
4131
|
-
# To setup your validator override the constructor.
|
4132
|
-
#
|
4133
|
-
# class MyValidator < ActiveModel::Validator
|
4134
|
-
# def initialize(options={})
|
4135
|
-
# super
|
4136
|
-
# options[:class].attr_accessor :custom_attribute
|
4137
|
-
# end
|
4138
|
-
# end
|
4139
|
-
class Validator
|
4140
|
-
attr_reader options: untyped
|
4141
|
-
|
4142
|
-
# Returns the kind of the validator.
|
4143
|
-
#
|
4144
|
-
# PresenceValidator.kind # => :presence
|
4145
|
-
# AcceptanceValidator.kind # => :acceptance
|
4146
|
-
def self.kind: () -> untyped
|
4147
|
-
|
4148
|
-
# Accepts options that will be made available through the +options+ reader.
|
4149
|
-
def initialize: (?::Hash[untyped, untyped] options) -> untyped
|
4150
|
-
|
4151
|
-
# Returns the kind for this validator.
|
4152
|
-
#
|
4153
|
-
# PresenceValidator.new(attributes: [:username]).kind # => :presence
|
4154
|
-
# AcceptanceValidator.new(attributes: [:terms]).kind # => :acceptance
|
4155
|
-
def kind: () -> untyped
|
4156
|
-
|
4157
|
-
# Override this method in subclasses with validation logic, adding errors
|
4158
|
-
# to the records +errors+ array where necessary.
|
4159
|
-
def validate: (untyped record) -> untyped
|
4160
|
-
end
|
4161
|
-
|
4162
|
-
class EachValidator < Validator
|
4163
|
-
# +EachValidator+ is a validator which iterates through the attributes given
|
4164
|
-
# in the options hash invoking the <tt>validate_each</tt> method passing in the
|
4165
|
-
# record, attribute and value.
|
4166
|
-
#
|
4167
|
-
# All \Active \Model validations are built on top of this validator.
|
4168
|
-
# nodoc:
|
4169
|
-
attr_reader attributes: untyped
|
4170
|
-
|
4171
|
-
# Returns a new validator instance. All options will be available via the
|
4172
|
-
# +options+ reader, however the <tt>:attributes</tt> option will be removed
|
4173
|
-
# and instead be made available through the +attributes+ reader.
|
4174
|
-
def initialize: (untyped options) -> untyped
|
4175
|
-
|
4176
|
-
# Performs validation on the supplied record. By default this will call
|
4177
|
-
# +validate_each+ to determine validity therefore subclasses should
|
4178
|
-
# override +validate_each+ with validation logic.
|
4179
|
-
def validate: (untyped record) -> untyped
|
4180
|
-
|
4181
|
-
# Override this method in subclasses with the validation logic, adding
|
4182
|
-
# errors to the records +errors+ array where necessary.
|
4183
|
-
def validate_each: (untyped record, untyped attribute, untyped value) -> untyped
|
4184
|
-
|
4185
|
-
# Hook method that gets called by the initializer allowing verification
|
4186
|
-
# that the arguments supplied are valid. You could for example raise an
|
4187
|
-
# +ArgumentError+ when invalid options are supplied.
|
4188
|
-
def check_validity!: () -> nil
|
4189
|
-
end
|
4190
|
-
|
4191
|
-
class BlockValidator < EachValidator
|
4192
|
-
# +BlockValidator+ is a special +EachValidator+ which receives a block on initialization
|
4193
|
-
# and call this block for each attribute being validated. +validates_each+ uses this validator.
|
4194
|
-
# nodoc:
|
4195
|
-
def initialize: (untyped options) { () -> untyped } -> untyped
|
4196
|
-
|
4197
|
-
def validate_each: (untyped record, untyped attribute, untyped value) -> untyped
|
4198
|
-
end
|
4199
|
-
end
|
4200
|
-
|
4201
|
-
module ActiveModel
|
4202
|
-
# Returns the version of the currently loaded \Active \Model as a <tt>Gem::Version</tt>
|
4203
|
-
def self.version: () -> untyped
|
4204
|
-
end
|
4205
|
-
|
4206
|
-
module ActiveModel
|
4207
|
-
extend ActiveSupport::Autoload
|
4208
|
-
|
4209
|
-
module Serializers
|
4210
|
-
extend ActiveSupport::Autoload
|
4211
|
-
end
|
4212
|
-
|
4213
|
-
def self.eager_load!: () -> untyped
|
4214
|
-
end
|