rbs_rails 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml 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
+