rbs_rails 0.1.0 → 0.2.0

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