lazy_migrate 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 +4 -4
- data/.gitignore +4 -0
- data/Appraisals +9 -0
- data/Gemfile.lock +133 -4
- data/Guardfile +39 -0
- data/README.md +56 -6
- data/Rakefile +1 -3
- data/bin/exe/lazy_migrate +14 -1
- data/gemfiles/.bundle/config +2 -0
- data/gemfiles/rails_5_1_5.gemfile +8 -0
- data/gemfiles/rails_5_1_5.gemfile.lock +170 -0
- data/gemfiles/rails_5_2_4_3.gemfile +8 -0
- data/gemfiles/rails_5_2_4_3.gemfile.lock +178 -0
- data/github/demo.gif +0 -0
- data/lazy_migrate.gemspec +9 -3
- data/lib/lazy_migrate.rb +6 -2
- data/lib/lazy_migrate/client.rb +123 -0
- data/lib/lazy_migrate/migration.rb +14 -0
- data/lib/lazy_migrate/migrator_adapter.rb +144 -0
- data/lib/lazy_migrate/migrator_adapter_factory.rb +24 -0
- data/lib/lazy_migrate/new_migrator_adapter.rb +85 -0
- data/lib/lazy_migrate/old_migrator_adapter.rb +97 -0
- data/lib/lazy_migrate/version.rb +2 -1
- data/lib/tasks/lazy_migrate.rake +10 -0
- data/sorbet/config +2 -0
- data/sorbet/rbi/gems/actioncable.rbi +393 -0
- data/sorbet/rbi/gems/actionmailer.rbi +425 -0
- data/sorbet/rbi/gems/actionpack.rbi +3230 -0
- data/sorbet/rbi/gems/actionview.rbi +1153 -0
- data/sorbet/rbi/gems/activejob.rbi +282 -0
- data/sorbet/rbi/gems/activemodel.rbi +742 -0
- data/sorbet/rbi/gems/activerecord.rbi +4004 -0
- data/sorbet/rbi/gems/activestorage.rbi +174 -0
- data/sorbet/rbi/gems/activesupport.rbi +2300 -0
- data/sorbet/rbi/gems/appraisal.rbi +151 -0
- data/sorbet/rbi/gems/arel.rbi +1253 -0
- data/sorbet/rbi/gems/byebug.rbi +1041 -0
- data/sorbet/rbi/gems/coderay.rbi +92 -0
- data/sorbet/rbi/gems/concurrent-ruby.rbi +1586 -0
- data/sorbet/rbi/gems/crass.rbi +93 -0
- data/sorbet/rbi/gems/erubi.rbi +27 -0
- data/sorbet/rbi/gems/globalid.rbi +99 -0
- data/sorbet/rbi/gems/i18n.rbi +192 -0
- data/sorbet/rbi/gems/loofah.rbi +131 -0
- data/sorbet/rbi/gems/mail.rbi +1092 -0
- data/sorbet/rbi/gems/marcel.rbi +13 -0
- data/sorbet/rbi/gems/method_source.rbi +64 -0
- data/sorbet/rbi/gems/mini_mime.rbi +52 -0
- data/sorbet/rbi/gems/minitest.rbi +282 -0
- data/sorbet/rbi/gems/nio4r.rbi +68 -0
- data/sorbet/rbi/gems/nokogiri.rbi +1011 -0
- data/sorbet/rbi/gems/pastel.rbi +119 -0
- data/sorbet/rbi/gems/pry-byebug.rbi +155 -0
- data/sorbet/rbi/gems/pry.rbi +1949 -0
- data/sorbet/rbi/gems/rack-test.rbi +162 -0
- data/sorbet/rbi/gems/rack.rbi +525 -0
- data/sorbet/rbi/gems/rails-dom-testing.rbi +68 -0
- data/sorbet/rbi/gems/rails-html-sanitizer.rbi +92 -0
- data/sorbet/rbi/gems/railties.rbi +724 -0
- data/sorbet/rbi/gems/rake.rbi +666 -0
- data/sorbet/rbi/gems/rspec-core.rbi +1939 -0
- data/sorbet/rbi/gems/rspec-expectations.rbi +1123 -0
- data/sorbet/rbi/gems/rspec-mocks.rbi +1090 -0
- data/sorbet/rbi/gems/rspec-support.rbi +280 -0
- data/sorbet/rbi/gems/rspec.rbi +15 -0
- data/sorbet/rbi/gems/sprockets-rails.rbi +106 -0
- data/sorbet/rbi/gems/sprockets.rbi +755 -0
- data/sorbet/rbi/gems/sqlite3.rbi +354 -0
- data/sorbet/rbi/gems/thor.rbi +580 -0
- data/sorbet/rbi/gems/thread_safe.rbi +82 -0
- data/sorbet/rbi/gems/tty-color.rbi +44 -0
- data/sorbet/rbi/gems/tty-cursor.rbi +72 -0
- data/sorbet/rbi/gems/tty-prompt.rbi +531 -0
- data/sorbet/rbi/gems/tty-reader.rbi +176 -0
- data/sorbet/rbi/gems/tty-screen.rbi +66 -0
- data/sorbet/rbi/gems/tzinfo.rbi +406 -0
- data/sorbet/rbi/gems/websocket-driver.rbi +103 -0
- data/sorbet/rbi/gems/websocket-extensions.rbi +29 -0
- data/sorbet/rbi/gems/wisper.rbi +130 -0
- data/sorbet/rbi/hidden-definitions/errors.txt +7584 -0
- data/sorbet/rbi/hidden-definitions/hidden.rbi +13328 -0
- data/sorbet/rbi/sorbet-typed/lib/actionmailer/all/actionmailer.rbi +13 -0
- data/sorbet/rbi/sorbet-typed/lib/actionpack/all/actionpack.rbi +954 -0
- data/sorbet/rbi/sorbet-typed/lib/actionview/all/actionview.rbi +321 -0
- data/sorbet/rbi/sorbet-typed/lib/activemodel/all/activemodel.rbi +597 -0
- data/sorbet/rbi/sorbet-typed/lib/activerecord/<6/activerecord.rbi +13 -0
- data/sorbet/rbi/sorbet-typed/lib/activerecord/>=5.2/activerecord.rbi +16 -0
- data/sorbet/rbi/sorbet-typed/lib/activerecord/>=5/activerecord.rbi +53 -0
- data/sorbet/rbi/sorbet-typed/lib/activerecord/all/activerecord.rbi +1454 -0
- data/sorbet/rbi/sorbet-typed/lib/activerecord/all/model_schema.rbi +79 -0
- data/sorbet/rbi/sorbet-typed/lib/activerecord/all/sanitization.rbi +36 -0
- data/sorbet/rbi/sorbet-typed/lib/activerecord/~>5.2.0/activerecord.rbi +447 -0
- data/sorbet/rbi/sorbet-typed/lib/activestorage/<=6.1/activestorage.rbi +82 -0
- data/sorbet/rbi/sorbet-typed/lib/activestorage/all/activestorage.rbi +177 -0
- data/sorbet/rbi/sorbet-typed/lib/activesupport/all/activesupport.rbi +1431 -0
- data/sorbet/rbi/sorbet-typed/lib/minitest/all/minitest.rbi +108 -0
- data/sorbet/rbi/sorbet-typed/lib/railties/all/railties.rbi +25 -0
- data/sorbet/rbi/todo.rbi +18 -0
- data/sorbet/rbi/user-defined/activerecord.rbi +56 -0
- metadata +181 -7
- data/lib/lazy_migrate/migrator.rb +0 -186
@@ -0,0 +1,321 @@
|
|
1
|
+
# This file is autogenerated. Do not edit it by hand. Regenerate it with:
|
2
|
+
# srb rbi sorbet-typed
|
3
|
+
#
|
4
|
+
# If you would like to make changes to this file, great! Please upstream any changes you make here:
|
5
|
+
#
|
6
|
+
# https://github.com/sorbet/sorbet-typed/edit/master/lib/actionview/all/actionview.rbi
|
7
|
+
#
|
8
|
+
# typed: strong
|
9
|
+
|
10
|
+
module ActionView
|
11
|
+
class ActionViewError < StandardError; end
|
12
|
+
class EncodingError < StandardError; end
|
13
|
+
class WrongEncodingError < EncodingError; end
|
14
|
+
|
15
|
+
class MissingTemplate < ActionViewError
|
16
|
+
sig { returns(String) }
|
17
|
+
def path; end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Template
|
21
|
+
class Error < ActionViewError; end
|
22
|
+
end
|
23
|
+
|
24
|
+
TemplateError = T.type_alias {Template::Error}
|
25
|
+
|
26
|
+
class SyntaxErrorInTemplate < Template::Error; end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Provides a set of methods for making links and getting URLs that
|
30
|
+
# depend on the routing subsystem (see ActionDispatch::Routing).
|
31
|
+
# This allows you to use the same format for links in views
|
32
|
+
# and controllers.
|
33
|
+
module ActionView::Helpers::UrlHelper
|
34
|
+
# Creates an anchor element of the given `name` using a URL created by the set of `options`.
|
35
|
+
# See the valid options in the documentation for `url_for`. It's also possible to
|
36
|
+
# pass a String instead of an options hash, which generates an anchor element that uses the
|
37
|
+
# value of the String as the href for the link. Using a `:back` Symbol instead
|
38
|
+
# of an options hash will generate a link to the referrer (a JavaScript back link
|
39
|
+
# will be used in place of a referrer if none exists). If `nil` is passed as the name
|
40
|
+
# the value of the link itself will become the name.
|
41
|
+
#
|
42
|
+
# #### Signatures
|
43
|
+
#
|
44
|
+
# ```ruby
|
45
|
+
# link_to(body, url, html_options = {})
|
46
|
+
# # url is a String; you can use URL helpers like
|
47
|
+
# # posts_path
|
48
|
+
#
|
49
|
+
# link_to(body, url_options = {}, html_options = {})
|
50
|
+
# # url_options, except :method, is passed to url_for
|
51
|
+
#
|
52
|
+
# link_to(options = {}, html_options = {}) do
|
53
|
+
# # name
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# link_to(url, html_options = {}) do
|
57
|
+
# # name
|
58
|
+
# end
|
59
|
+
# ```
|
60
|
+
#
|
61
|
+
# #### Options
|
62
|
+
# * `:data` - This option can be used to add custom data attributes.
|
63
|
+
# * `method: symbol of HTTP verb` - This modifier will dynamically
|
64
|
+
# create an HTML form and immediately submit the form for processing using
|
65
|
+
# the HTTP verb specified. Useful for having links perform a POST operation
|
66
|
+
# in dangerous actions like deleting a record (which search bots can follow
|
67
|
+
# while spidering your site). Supported verbs are `:post`, `:delete`, `:patch`, and `:put`.
|
68
|
+
# Note that if the user has JavaScript disabled, the request will fall back
|
69
|
+
# to using GET. If `href: '#'` is used and the user has JavaScript
|
70
|
+
# disabled clicking the link will have no effect. If you are relying on the
|
71
|
+
# POST behavior, you should check for it in your controller's action by using
|
72
|
+
# the request object's methods for `post?`, `delete?`, `patch?`, or `put?`.
|
73
|
+
# * `remote: true` - This will allow the unobtrusive JavaScript
|
74
|
+
# driver to make an Ajax request to the URL in question instead of following
|
75
|
+
# the link. The drivers each provide mechanisms for listening for the
|
76
|
+
# completion of the Ajax request and performing JavaScript operations once
|
77
|
+
# they're complete
|
78
|
+
#
|
79
|
+
# #### Data attributes
|
80
|
+
#
|
81
|
+
# * `confirm: 'question?'` - This will allow the unobtrusive JavaScript
|
82
|
+
# driver to prompt with the question specified (in this case, the
|
83
|
+
# resulting text would be `question?`. If the user accepts, the
|
84
|
+
# link is processed normally, otherwise no action is taken.
|
85
|
+
# * `:disable_with` - Value of this parameter will be used as the
|
86
|
+
# name for a disabled version of the link. This feature is provided by
|
87
|
+
# the unobtrusive JavaScript driver.
|
88
|
+
#
|
89
|
+
# #### Examples
|
90
|
+
# Because it relies on `url_for`, `link_to` supports both older-style controller/action/id arguments
|
91
|
+
# and newer RESTful routes. Current Rails style favors RESTful routes whenever possible, so base
|
92
|
+
# your application on resources and use
|
93
|
+
#
|
94
|
+
# ```ruby
|
95
|
+
# link_to "Profile", profile_path(@profile)
|
96
|
+
# # => <a href="/profiles/1">Profile</a>
|
97
|
+
# ```
|
98
|
+
#
|
99
|
+
# or the even pithier
|
100
|
+
#
|
101
|
+
# ```ruby
|
102
|
+
# link_to "Profile", @profile
|
103
|
+
# # => <a href="/profiles/1">Profile</a>
|
104
|
+
# ```
|
105
|
+
#
|
106
|
+
# in place of the older more verbose, non-resource-oriented
|
107
|
+
#
|
108
|
+
# ```ruby
|
109
|
+
# link_to "Profile", controller: "profiles", action: "show", id: @profile
|
110
|
+
# # => <a href="/profiles/show/1">Profile</a>
|
111
|
+
# ```
|
112
|
+
#
|
113
|
+
# Similarly,
|
114
|
+
#
|
115
|
+
# ```ruby
|
116
|
+
# link_to "Profiles", profiles_path
|
117
|
+
# # => <a href="/profiles">Profiles</a>
|
118
|
+
# ```
|
119
|
+
#
|
120
|
+
# is better than
|
121
|
+
#
|
122
|
+
# ```ruby
|
123
|
+
# link_to "Profiles", controller: "profiles"
|
124
|
+
# # => <a href="/profiles">Profiles</a>
|
125
|
+
# ```
|
126
|
+
#
|
127
|
+
# When name is `nil` the href is presented instead
|
128
|
+
#
|
129
|
+
# ```ruby
|
130
|
+
# link_to nil, "http://example.com"
|
131
|
+
# # => <a href="http://www.example.com">http://www.example.com</a>
|
132
|
+
# ```
|
133
|
+
#
|
134
|
+
# You can use a block as well if your link target is hard to fit into the name parameter. ERB example:
|
135
|
+
#
|
136
|
+
# ```html
|
137
|
+
# <%= link_to(@profile) do %>
|
138
|
+
# <strong><%= @profile.name %></strong> -- <span>Check it out!</span>
|
139
|
+
# <% end %>
|
140
|
+
# # => <a href="/profiles/1">
|
141
|
+
# <strong>David</strong> -- <span>Check it out!</span>
|
142
|
+
# </a>
|
143
|
+
# ```
|
144
|
+
#
|
145
|
+
# Classes and ids for CSS are easy to produce:
|
146
|
+
#
|
147
|
+
# ```ruby
|
148
|
+
# link_to "Articles", articles_path, id: "news", class: "article"
|
149
|
+
# # => <a href="/articles" class="article" id="news">Articles</a>
|
150
|
+
# ```
|
151
|
+
#
|
152
|
+
# Be careful when using the older argument style, as an extra literal hash is needed:
|
153
|
+
#
|
154
|
+
# ```ruby
|
155
|
+
# link_to "Articles", { controller: "articles" }, id: "news", class: "article"
|
156
|
+
# # => <a href="/articles" class="article" id="news">Articles</a>
|
157
|
+
# ```
|
158
|
+
#
|
159
|
+
# Leaving the hash off gives the wrong link:
|
160
|
+
#
|
161
|
+
# ```ruby
|
162
|
+
# link_to "WRONG!", controller: "articles", id: "news", class: "article"
|
163
|
+
# # => <a href="/articles/index/news?class=article">WRONG!</a>
|
164
|
+
# ```
|
165
|
+
#
|
166
|
+
# `link_to` can also produce links with anchors or query strings:
|
167
|
+
#
|
168
|
+
# ```ruby
|
169
|
+
# link_to "Comment wall", profile_path(@profile, anchor: "wall")
|
170
|
+
# # => <a href="/profiles/1#wall">Comment wall</a>
|
171
|
+
#
|
172
|
+
# link_to "Ruby on Rails search", controller: "searches", query: "ruby on rails"
|
173
|
+
# # => <a href="/searches?query=ruby+on+rails">Ruby on Rails search</a>
|
174
|
+
#
|
175
|
+
# link_to "Nonsense search", searches_path(foo: "bar", baz: "quux")
|
176
|
+
# # => <a href="/searches?foo=bar&baz=quux">Nonsense search</a>
|
177
|
+
# ```
|
178
|
+
#
|
179
|
+
# The only option specific to `link_to` (`:method`) is used as follows:
|
180
|
+
#
|
181
|
+
# ```ruby
|
182
|
+
# link_to("Destroy", "http://www.example.com", method: :delete)
|
183
|
+
# # => <a href='http://www.example.com' rel="nofollow" data-method="delete">Destroy</a>
|
184
|
+
# ```
|
185
|
+
#
|
186
|
+
# You can also use custom data attributes using the `:data` option:
|
187
|
+
#
|
188
|
+
# ```ruby
|
189
|
+
# link_to "Visit Other Site", "http://www.rubyonrails.org/", data: { confirm: "Are you sure?" }
|
190
|
+
# # => <a href="http://www.rubyonrails.org/" data-confirm="Are you sure?">Visit Other Site</a>
|
191
|
+
# ```
|
192
|
+
#
|
193
|
+
# Also you can set any link attributes such as `target`, `rel`, `type`:
|
194
|
+
#
|
195
|
+
# ```ruby
|
196
|
+
# link_to "External link", "http://www.rubyonrails.org/", target: "_blank", rel: "nofollow"
|
197
|
+
# # => <a href="http://www.rubyonrails.org/" target="_blank" rel="nofollow">External link</a>
|
198
|
+
# ```
|
199
|
+
sig do
|
200
|
+
params(
|
201
|
+
name: String,
|
202
|
+
options: T.untyped,
|
203
|
+
html_options: T.untyped,
|
204
|
+
block: T.untyped
|
205
|
+
).returns(ActiveSupport::SafeBuffer)
|
206
|
+
end
|
207
|
+
def link_to(name = nil, options = nil, html_options = nil, &block); end
|
208
|
+
|
209
|
+
# Creates a link tag of the given `name` using a URL created by the set of
|
210
|
+
# `options` if `condition` is true, otherwise only the name is
|
211
|
+
# returned. To specialize the default behavior, you can pass a block that
|
212
|
+
# accepts the name or the full argument list for `link_to_unless` (see the examples
|
213
|
+
# in `link_to_unless`).
|
214
|
+
#
|
215
|
+
# #### Examples
|
216
|
+
# ```ruby
|
217
|
+
# <%= link_to_if(@current_user.nil?, "Login", { controller: "sessions", action: "new" }) %>
|
218
|
+
# # If the user isn't logged in...
|
219
|
+
# # => <a href="/sessions/new/">Login</a>
|
220
|
+
# ```
|
221
|
+
#
|
222
|
+
# ```ruby
|
223
|
+
# <%=
|
224
|
+
# link_to_if(@current_user.nil?, "Login", { controller: "sessions", action: "new" }) do
|
225
|
+
# link_to(@current_user.login, { controller: "accounts", action: "show", id: @current_user })
|
226
|
+
# end
|
227
|
+
# %>
|
228
|
+
# # If the user isn't logged in...
|
229
|
+
# # => <a href="/sessions/new/">Login</a>
|
230
|
+
# # If they are logged in...
|
231
|
+
# # => <a href="/accounts/show/3">my_username</a>
|
232
|
+
# ```
|
233
|
+
sig do
|
234
|
+
params(
|
235
|
+
condition: T.untyped,
|
236
|
+
name: String,
|
237
|
+
options: T.untyped,
|
238
|
+
html_options: T.untyped,
|
239
|
+
block: T.untyped
|
240
|
+
).returns(T.untyped)
|
241
|
+
end
|
242
|
+
def link_to_if(condition, name, options = {}, html_options = {}, &block); end
|
243
|
+
|
244
|
+
# True if the current request URI was generated by the given `options`.
|
245
|
+
#
|
246
|
+
# #### Examples
|
247
|
+
# Let's say we're in the `http://www.example.com/shop/checkout?order=desc&page=1` action.
|
248
|
+
#
|
249
|
+
# ```ruby
|
250
|
+
# current_page?(action: 'process')
|
251
|
+
# # => false
|
252
|
+
#
|
253
|
+
# current_page?(action: 'checkout')
|
254
|
+
# # => true
|
255
|
+
#
|
256
|
+
# current_page?(controller: 'library', action: 'checkout')
|
257
|
+
# # => false
|
258
|
+
#
|
259
|
+
# current_page?(controller: 'shop', action: 'checkout')
|
260
|
+
# # => true
|
261
|
+
#
|
262
|
+
# current_page?(controller: 'shop', action: 'checkout', order: 'asc')
|
263
|
+
# # => false
|
264
|
+
#
|
265
|
+
# current_page?(controller: 'shop', action: 'checkout', order: 'desc', page: '1')
|
266
|
+
# # => true
|
267
|
+
#
|
268
|
+
# current_page?(controller: 'shop', action: 'checkout', order: 'desc', page: '2')
|
269
|
+
# # => false
|
270
|
+
#
|
271
|
+
# current_page?('http://www.example.com/shop/checkout')
|
272
|
+
# # => true
|
273
|
+
#
|
274
|
+
# current_page?('http://www.example.com/shop/checkout', check_parameters: true)
|
275
|
+
# # => false
|
276
|
+
#
|
277
|
+
# current_page?('/shop/checkout')
|
278
|
+
# # => true
|
279
|
+
#
|
280
|
+
# current_page?('http://www.example.com/shop/checkout?order=desc&page=1')
|
281
|
+
# # => true
|
282
|
+
# ```
|
283
|
+
#
|
284
|
+
# Let's say we're in the `http://www.example.com/products` action with method POST in case of invalid product.
|
285
|
+
#
|
286
|
+
# ```ruby
|
287
|
+
# current_page?(controller: 'product', action: 'index')
|
288
|
+
# # => false
|
289
|
+
# ```
|
290
|
+
#
|
291
|
+
# We can also pass in the symbol arguments instead of strings.
|
292
|
+
sig { params(options: T.untyped, check_parameters: T::Boolean).returns(T::Boolean) }
|
293
|
+
def current_page?(options, check_parameters: false); end
|
294
|
+
end
|
295
|
+
|
296
|
+
module ActionView::Layouts
|
297
|
+
extend T::Helpers
|
298
|
+
|
299
|
+
mixes_in_class_methods(ActionView::Layouts::ClassMethods)
|
300
|
+
end
|
301
|
+
|
302
|
+
module ActionView::Layouts::ClassMethods
|
303
|
+
end
|
304
|
+
|
305
|
+
module ActionView::Rendering
|
306
|
+
extend T::Helpers
|
307
|
+
|
308
|
+
mixes_in_class_methods(ActionView::Rendering::ClassMethods)
|
309
|
+
end
|
310
|
+
|
311
|
+
module ActionView::Rendering::ClassMethods
|
312
|
+
end
|
313
|
+
|
314
|
+
module ActionView::ViewPaths
|
315
|
+
extend T::Helpers
|
316
|
+
|
317
|
+
mixes_in_class_methods(ActionView::ViewPaths::ClassMethods)
|
318
|
+
end
|
319
|
+
|
320
|
+
module ActionView::ViewPaths::ClassMethods
|
321
|
+
end
|
@@ -0,0 +1,597 @@
|
|
1
|
+
# This file is autogenerated. Do not edit it by hand. Regenerate it with:
|
2
|
+
# srb rbi sorbet-typed
|
3
|
+
#
|
4
|
+
# If you would like to make changes to this file, great! Please upstream any changes you make here:
|
5
|
+
#
|
6
|
+
# https://github.com/sorbet/sorbet-typed/edit/master/lib/activemodel/all/activemodel.rbi
|
7
|
+
#
|
8
|
+
# typed: false
|
9
|
+
|
10
|
+
module ActiveModel::Dirty
|
11
|
+
extend T::Sig
|
12
|
+
sig { params(attr: Symbol, from: T.untyped, to: T.untyped).returns(T::Boolean) }
|
13
|
+
def attribute_changed?(attr, from: nil, to: nil); end
|
14
|
+
|
15
|
+
sig { params(attr_name: Symbol).returns(T::Boolean) }
|
16
|
+
def attribute_changed_in_place?(attr_name); end
|
17
|
+
|
18
|
+
sig { params(attr_name: Symbol).returns(T::Boolean) }
|
19
|
+
def attribute_previously_changed?(attr_name); end
|
20
|
+
|
21
|
+
sig { returns(T::Boolean) }
|
22
|
+
def changed?; end
|
23
|
+
end
|
24
|
+
|
25
|
+
module ActiveModel::Validations
|
26
|
+
# Returns the `Errors` object that holds all information about attribute
|
27
|
+
# error messages.
|
28
|
+
#
|
29
|
+
# ```ruby
|
30
|
+
# class Person
|
31
|
+
# include ActiveModel::Validations
|
32
|
+
#
|
33
|
+
# attr_accessor :name
|
34
|
+
# validates_presence_of :name
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# person = Person.new
|
38
|
+
# person.valid? # => false
|
39
|
+
# person.errors # => #<ActiveModel::Errors:0x007fe603816640 @messages={name:["can't be blank"]}>
|
40
|
+
# ```
|
41
|
+
sig { returns(ActiveModel::Errors) }
|
42
|
+
def errors; end
|
43
|
+
|
44
|
+
module ClassMethods
|
45
|
+
# https://github.com/rails/rails/blob/v5.2.3/activemodel/lib/active_model/validations.rb#L136-L154
|
46
|
+
sig do
|
47
|
+
params(
|
48
|
+
names: T.any(Symbol, String),
|
49
|
+
if: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
50
|
+
on: T.any(Symbol, String, T::Array[T.any(Symbol, String)]),
|
51
|
+
prepend: T::Boolean,
|
52
|
+
unless: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
53
|
+
).void
|
54
|
+
end
|
55
|
+
def validate(
|
56
|
+
*names,
|
57
|
+
if: nil,
|
58
|
+
on: nil,
|
59
|
+
prepend: false,
|
60
|
+
unless: nil
|
61
|
+
); end
|
62
|
+
|
63
|
+
# https://github.com/rails/rails/blob/v5.2.3/activemodel/lib/active_model/validations/validates.rb#L75-L105
|
64
|
+
sig do
|
65
|
+
params(
|
66
|
+
names: T.any(Symbol, String), # a splat of at least one attribute name
|
67
|
+
absence: T.any(T::Boolean, T::Hash[T.untyped, T.untyped]),
|
68
|
+
acceptance: T.any(T::Boolean, T::Hash[T.untyped, T.untyped]),
|
69
|
+
allow_blank: T::Boolean,
|
70
|
+
allow_nil: T::Boolean,
|
71
|
+
confirmation: T.any(T::Boolean, T::Hash[T.untyped, T.untyped]),
|
72
|
+
# `exclusion` and `inclusion` are tricky to type without better support
|
73
|
+
# for overloading and shapes. Value can be anything that responds to
|
74
|
+
# `include?` (e.g. (1..3)), or a hash having an `in` or `within` key,
|
75
|
+
# like { in: [1, 2, 3], ... }
|
76
|
+
exclusion: T::Enumerable[T.untyped],
|
77
|
+
# `format` hash must additionally contain either :with or :without keys.
|
78
|
+
# Alternatively, it can be a Regexp.
|
79
|
+
format: T.any(T::Hash[T.untyped, T.untyped], Regexp),
|
80
|
+
if: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
81
|
+
# `exclusion` and `inclusion` are tricky to type without better support
|
82
|
+
# for overloading and shapes. Value can be anything that responds to
|
83
|
+
# `include?` (e.g. (1..3)), or a hash having an `in` or `within` key,
|
84
|
+
# like { in: [1, 2, 3], ... }
|
85
|
+
inclusion: T::Enumerable[T.untyped],
|
86
|
+
# if Hash, must contain :in, :within, :maximum, :minimum, or :is keys
|
87
|
+
length: T.any(T::Range[T.untyped], T::Hash[T.untyped, T.untyped]),
|
88
|
+
numericality: T.any(T::Boolean, T::Hash[T.untyped, T.untyped]),
|
89
|
+
on: T.any(Symbol, String, T::Array[T.any(Symbol, String)]),
|
90
|
+
presence: T.any(T::Boolean, T::Hash[T.untyped, T.untyped]),
|
91
|
+
size: T.any(T::Boolean, T::Hash[T.untyped, T.untyped]),
|
92
|
+
strict: T::Boolean,
|
93
|
+
uniqueness: T.any(T::Boolean, T::Hash[T.untyped, T.untyped]),
|
94
|
+
unless: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
95
|
+
kwargs: T.untyped
|
96
|
+
).void
|
97
|
+
end
|
98
|
+
def validates(
|
99
|
+
*names,
|
100
|
+
absence: false,
|
101
|
+
acceptance: {},
|
102
|
+
allow_blank: false,
|
103
|
+
allow_nil: false,
|
104
|
+
confirmation: false,
|
105
|
+
exclusion: [],
|
106
|
+
format: {},
|
107
|
+
if: nil,
|
108
|
+
inclusion: [],
|
109
|
+
length: {},
|
110
|
+
numericality: false,
|
111
|
+
on: :_,
|
112
|
+
presence: false,
|
113
|
+
size: false,
|
114
|
+
strict: false,
|
115
|
+
uniqueness: false,
|
116
|
+
unless: :_,
|
117
|
+
**kwargs
|
118
|
+
)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
mixes_in_class_methods(ClassMethods)
|
123
|
+
end
|
124
|
+
|
125
|
+
class ActiveModel::Type::Value
|
126
|
+
extend T::Sig
|
127
|
+
|
128
|
+
sig { params(precision: T.untyped, limit: T.untyped, scale: T.untyped).void }
|
129
|
+
def initialize(precision: nil, limit: nil, scale: nil); end
|
130
|
+
|
131
|
+
sig { params(value: T.untyped).returns(T.untyped) }
|
132
|
+
def cast(value); end
|
133
|
+
end
|
134
|
+
|
135
|
+
class ActiveModel::Type::Boolean < ActiveModel::Type::Value
|
136
|
+
sig { params(arg0: T.untyped).returns(T.nilable(T::Boolean))}
|
137
|
+
def cast(arg0); end
|
138
|
+
end
|
139
|
+
|
140
|
+
class ActiveModel::Type::ImmutableString < ActiveModel::Type::Value
|
141
|
+
sig { params(arg0: T.untyped).returns(T.nilable(String))}
|
142
|
+
def cast(arg0); end
|
143
|
+
end
|
144
|
+
|
145
|
+
class ActiveModel::Type::String < ActiveModel::Type::ImmutableString
|
146
|
+
sig { params(arg0: T.untyped).returns(T.nilable(String))}
|
147
|
+
def cast(arg0); end
|
148
|
+
end
|
149
|
+
|
150
|
+
module ActiveModel::Validations::HelperMethods
|
151
|
+
# A type alias for the in/within parameters on the
|
152
|
+
# validates_(inclusion/exclusion)_of methods.
|
153
|
+
InWithinType = T.type_alias do
|
154
|
+
T.nilable(
|
155
|
+
T.any(
|
156
|
+
Symbol,
|
157
|
+
String,
|
158
|
+
T::Array[T.any(String, Symbol)],
|
159
|
+
T::Range[Integer],
|
160
|
+
T::Array[T::Boolean],
|
161
|
+
T.proc.params(arg0: T.untyped).returns(T::Boolean)
|
162
|
+
)
|
163
|
+
)
|
164
|
+
end
|
165
|
+
|
166
|
+
module ClassMethods
|
167
|
+
sig do
|
168
|
+
params(
|
169
|
+
attr_names: T.any(String, Symbol),
|
170
|
+
message: String,
|
171
|
+
if: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
172
|
+
unless: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
173
|
+
on: T.any(Symbol, String, T::Array[T.any(Symbol, String)]),
|
174
|
+
allow_nil: T::Boolean,
|
175
|
+
allow_blank: T::Boolean,
|
176
|
+
strict: T::Boolean
|
177
|
+
).void
|
178
|
+
end
|
179
|
+
def validates_absence_of(
|
180
|
+
*attr_names,
|
181
|
+
message: 'must be blank',
|
182
|
+
if: nil,
|
183
|
+
unless: :_,
|
184
|
+
on: :_,
|
185
|
+
allow_nil: false,
|
186
|
+
allow_blank: false,
|
187
|
+
strict: false
|
188
|
+
); end
|
189
|
+
|
190
|
+
sig do
|
191
|
+
params(
|
192
|
+
attr_names: T.any(String, Symbol),
|
193
|
+
message: String,
|
194
|
+
accept: T.untyped,
|
195
|
+
if: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
196
|
+
unless: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
197
|
+
on: T.any(Symbol, String, T::Array[T.any(Symbol, String)]),
|
198
|
+
allow_nil: T::Boolean,
|
199
|
+
allow_blank: T::Boolean,
|
200
|
+
strict: T::Boolean
|
201
|
+
).void
|
202
|
+
end
|
203
|
+
def validates_acceptance_of(
|
204
|
+
*attr_names,
|
205
|
+
message: 'must be accepted',
|
206
|
+
accept: ['1', true],
|
207
|
+
if: nil,
|
208
|
+
unless: :_,
|
209
|
+
on: :_,
|
210
|
+
allow_nil: false,
|
211
|
+
allow_blank: false,
|
212
|
+
strict: false
|
213
|
+
); end
|
214
|
+
|
215
|
+
sig do
|
216
|
+
params(
|
217
|
+
attr_names: T.any(String, Symbol),
|
218
|
+
message: String,
|
219
|
+
case_sensitive: T::Boolean,
|
220
|
+
if: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
221
|
+
unless: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
222
|
+
on: T.any(Symbol, String, T::Array[T.any(Symbol, String)]),
|
223
|
+
allow_nil: T::Boolean,
|
224
|
+
allow_blank: T::Boolean,
|
225
|
+
strict: T::Boolean
|
226
|
+
).void
|
227
|
+
end
|
228
|
+
def validates_confirmation_of(
|
229
|
+
*attr_names,
|
230
|
+
message: "doesn't match %{translated_attribute_name}",
|
231
|
+
case_sensitive: true,
|
232
|
+
if: nil,
|
233
|
+
unless: :_,
|
234
|
+
on: :_,
|
235
|
+
allow_nil: false,
|
236
|
+
allow_blank: false,
|
237
|
+
strict: false
|
238
|
+
); end
|
239
|
+
|
240
|
+
sig do
|
241
|
+
params(
|
242
|
+
attr_names: T.any(String, Symbol),
|
243
|
+
message: String,
|
244
|
+
in: InWithinType,
|
245
|
+
within: InWithinType,
|
246
|
+
if: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
247
|
+
unless: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
248
|
+
on: T.any(Symbol, String, T::Array[T.any(Symbol, String)]),
|
249
|
+
allow_nil: T::Boolean,
|
250
|
+
allow_blank: T::Boolean,
|
251
|
+
strict: T::Boolean
|
252
|
+
).void
|
253
|
+
end
|
254
|
+
def validates_exclusion_of(
|
255
|
+
*attr_names,
|
256
|
+
message: 'is reserved',
|
257
|
+
in: nil,
|
258
|
+
within: nil,
|
259
|
+
if: nil,
|
260
|
+
unless: :_,
|
261
|
+
on: :_,
|
262
|
+
allow_nil: false,
|
263
|
+
allow_blank: false,
|
264
|
+
strict: false
|
265
|
+
); end
|
266
|
+
|
267
|
+
sig do
|
268
|
+
params(
|
269
|
+
attr_names: T.any(String, Symbol),
|
270
|
+
message: String,
|
271
|
+
with: T.untyped,
|
272
|
+
without: T.untyped,
|
273
|
+
multiline: T.untyped,
|
274
|
+
if: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
275
|
+
unless: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
276
|
+
on: T.any(Symbol, String, T::Array[T.any(Symbol, String)]),
|
277
|
+
allow_nil: T::Boolean,
|
278
|
+
allow_blank: T::Boolean,
|
279
|
+
strict: T::Boolean
|
280
|
+
).void
|
281
|
+
end
|
282
|
+
def validates_format_of(
|
283
|
+
*attr_names,
|
284
|
+
message: 'is invalid',
|
285
|
+
with: nil,
|
286
|
+
without: nil,
|
287
|
+
multiline: nil,
|
288
|
+
if: nil,
|
289
|
+
unless: :_,
|
290
|
+
on: :_,
|
291
|
+
allow_nil: false,
|
292
|
+
allow_blank: false,
|
293
|
+
strict: false
|
294
|
+
); end
|
295
|
+
|
296
|
+
sig do
|
297
|
+
params(
|
298
|
+
attr_names: T.any(String, Symbol),
|
299
|
+
message: String,
|
300
|
+
in: InWithinType,
|
301
|
+
within: InWithinType,
|
302
|
+
if: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
303
|
+
unless: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
304
|
+
on: T.any(Symbol, String, T::Array[T.any(Symbol, String)]),
|
305
|
+
allow_nil: T::Boolean,
|
306
|
+
allow_blank: T::Boolean,
|
307
|
+
strict: T::Boolean
|
308
|
+
).void
|
309
|
+
end
|
310
|
+
def validates_inclusion_of(
|
311
|
+
*attr_names,
|
312
|
+
message: 'is not included in the list',
|
313
|
+
in: nil,
|
314
|
+
within: nil,
|
315
|
+
if: nil,
|
316
|
+
unless: :_,
|
317
|
+
on: :_,
|
318
|
+
allow_nil: false,
|
319
|
+
allow_blank: false,
|
320
|
+
strict: false
|
321
|
+
); end
|
322
|
+
|
323
|
+
sig do
|
324
|
+
params(
|
325
|
+
attr_names: T.any(String, Symbol),
|
326
|
+
message: T.nilable(String),
|
327
|
+
minimum: T.nilable(Integer),
|
328
|
+
maximum: T.nilable(Integer),
|
329
|
+
is: T.nilable(Integer),
|
330
|
+
within: T.nilable(T::Range[Integer]),
|
331
|
+
in: T.nilable(T::Range[Integer]),
|
332
|
+
too_long: String,
|
333
|
+
too_short: String,
|
334
|
+
wrong_length: String,
|
335
|
+
if: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
336
|
+
unless: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
337
|
+
on: T.any(Symbol, String, T::Array[T.any(Symbol, String)]),
|
338
|
+
allow_nil: T::Boolean,
|
339
|
+
allow_blank: T::Boolean,
|
340
|
+
strict: T::Boolean
|
341
|
+
).void
|
342
|
+
end
|
343
|
+
def validates_length_of(
|
344
|
+
*attr_names,
|
345
|
+
message: nil,
|
346
|
+
minimum: nil,
|
347
|
+
maximum: nil,
|
348
|
+
is: nil,
|
349
|
+
within: nil,
|
350
|
+
in: nil,
|
351
|
+
too_long: 'is too long (maximum is %{count} characters)',
|
352
|
+
too_short: 'is too short (minimum is %{count} characters)',
|
353
|
+
wrong_length: 'is the wrong length (should be %{count} characters)',
|
354
|
+
if: nil,
|
355
|
+
unless: :_,
|
356
|
+
on: :_,
|
357
|
+
allow_nil: false,
|
358
|
+
allow_blank: false,
|
359
|
+
strict: false
|
360
|
+
); end
|
361
|
+
|
362
|
+
# validates_size_of is an alias of validates_length_of
|
363
|
+
sig do
|
364
|
+
params(
|
365
|
+
attr_names: T.any(String, Symbol),
|
366
|
+
message: T.nilable(String),
|
367
|
+
minimum: T.nilable(Integer),
|
368
|
+
maximum: T.nilable(Integer),
|
369
|
+
is: T.nilable(Integer),
|
370
|
+
within: T.nilable(T::Range[Integer]),
|
371
|
+
in: T.nilable(T::Range[Integer]),
|
372
|
+
too_long: String,
|
373
|
+
too_short: String,
|
374
|
+
wrong_length: String,
|
375
|
+
if: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
376
|
+
unless: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
377
|
+
on: T.any(Symbol, String, T::Array[T.any(Symbol, String)]),
|
378
|
+
allow_nil: T::Boolean,
|
379
|
+
allow_blank: T::Boolean,
|
380
|
+
strict: T::Boolean
|
381
|
+
).void
|
382
|
+
end
|
383
|
+
def validates_size_of(
|
384
|
+
*attr_names,
|
385
|
+
message: nil,
|
386
|
+
minimum: nil,
|
387
|
+
maximum: nil,
|
388
|
+
is: nil,
|
389
|
+
within: nil,
|
390
|
+
in: nil,
|
391
|
+
too_long: 'is too long (maximum is %{count} characters)',
|
392
|
+
too_short: 'is too short (minimum is %{count} characters)',
|
393
|
+
wrong_length: 'is the wrong length (should be %{count} characters)',
|
394
|
+
if: nil,
|
395
|
+
unless: :_,
|
396
|
+
on: :_,
|
397
|
+
allow_nil: false,
|
398
|
+
allow_blank: false,
|
399
|
+
strict: false
|
400
|
+
); end
|
401
|
+
|
402
|
+
# Create a type alias so we don't have to repeat this long type signature 6 times.
|
403
|
+
NumberComparatorType = T.type_alias {T.nilable(T.any(Integer, Float, T.proc.params(arg0: T.untyped).returns(T::Boolean), Symbol))}
|
404
|
+
sig do
|
405
|
+
params(
|
406
|
+
attr_names: T.any(String, Symbol),
|
407
|
+
message: String,
|
408
|
+
only_integer: T::Boolean,
|
409
|
+
greater_than: NumberComparatorType,
|
410
|
+
greater_than_or_equal_to: NumberComparatorType,
|
411
|
+
equal_to: NumberComparatorType,
|
412
|
+
less_than: NumberComparatorType,
|
413
|
+
less_than_or_equal_to: NumberComparatorType,
|
414
|
+
other_than: NumberComparatorType,
|
415
|
+
odd: T::Boolean,
|
416
|
+
even: T::Boolean,
|
417
|
+
if: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
418
|
+
unless: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
419
|
+
on: T.any(Symbol, String, T::Array[T.any(Symbol, String)]),
|
420
|
+
allow_nil: T::Boolean,
|
421
|
+
allow_blank: T::Boolean,
|
422
|
+
strict: T::Boolean
|
423
|
+
).void
|
424
|
+
end
|
425
|
+
def validates_numericality_of(
|
426
|
+
*attr_names,
|
427
|
+
message: 'is not a number',
|
428
|
+
only_integer: false,
|
429
|
+
greater_than: nil,
|
430
|
+
greater_than_or_equal_to: nil,
|
431
|
+
equal_to: nil,
|
432
|
+
less_than: nil,
|
433
|
+
less_than_or_equal_to: nil,
|
434
|
+
other_than: nil,
|
435
|
+
odd: false,
|
436
|
+
even: false,
|
437
|
+
if: nil,
|
438
|
+
unless: :_,
|
439
|
+
on: :_,
|
440
|
+
allow_nil: false,
|
441
|
+
allow_blank: false,
|
442
|
+
strict: false
|
443
|
+
); end
|
444
|
+
|
445
|
+
sig do
|
446
|
+
params(
|
447
|
+
attr_names: T.any(String, Symbol),
|
448
|
+
message: String,
|
449
|
+
if: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
450
|
+
unless: T.any(Symbol, String, T.proc.params(arg0: T.untyped).returns(T::Boolean)),
|
451
|
+
on: T.any(Symbol, String, T::Array[T.any(Symbol, String)]),
|
452
|
+
allow_nil: T::Boolean,
|
453
|
+
allow_blank: T::Boolean,
|
454
|
+
strict: T::Boolean
|
455
|
+
).void
|
456
|
+
end
|
457
|
+
def validates_presence_of(
|
458
|
+
*attr_names,
|
459
|
+
message: "can't be blank",
|
460
|
+
if: nil,
|
461
|
+
unless: :_,
|
462
|
+
on: :_,
|
463
|
+
allow_nil: false,
|
464
|
+
allow_blank: false,
|
465
|
+
strict: false
|
466
|
+
); end
|
467
|
+
end
|
468
|
+
|
469
|
+
mixes_in_class_methods(ClassMethods)
|
470
|
+
end
|
471
|
+
|
472
|
+
class ActiveModel::Errors
|
473
|
+
# Adds `message` to the error messages and used validator type to `details` on `attribute`.
|
474
|
+
# More than one error can be added to the same `attribute`.
|
475
|
+
# If no `message` is supplied, `:invalid` is assumed.
|
476
|
+
#
|
477
|
+
# ```ruby
|
478
|
+
# person.errors.add(:name)
|
479
|
+
# # => ["is invalid"]
|
480
|
+
# person.errors.add(:name, :not_implemented, message: "must be implemented")
|
481
|
+
# # => ["is invalid", "must be implemented"]
|
482
|
+
# ```
|
483
|
+
#
|
484
|
+
# ```ruby
|
485
|
+
# person.errors.messages
|
486
|
+
# # => {:name=>["is invalid", "must be implemented"]}
|
487
|
+
# ```
|
488
|
+
#
|
489
|
+
# ```ruby
|
490
|
+
# person.errors.details
|
491
|
+
# # => {:name=>[{error: :not_implemented}, {error: :invalid}]}
|
492
|
+
# ```
|
493
|
+
#
|
494
|
+
# If `message` is a symbol, it will be translated using the appropriate
|
495
|
+
# scope (see `generate_message`).
|
496
|
+
#
|
497
|
+
# If `message` is a proc, it will be called, allowing for things like
|
498
|
+
# `Time.now` to be used within an error.
|
499
|
+
#
|
500
|
+
# If the `:strict` option is set to `true`, it will raise
|
501
|
+
# ActiveModel::StrictValidationFailed instead of adding the error.
|
502
|
+
# `:strict` option can also be set to any other exception.
|
503
|
+
#
|
504
|
+
# ```ruby
|
505
|
+
# person.errors.add(:name, :invalid, strict: true)
|
506
|
+
# # => ActiveModel::StrictValidationFailed: Name is invalid
|
507
|
+
# person.errors.add(:name, :invalid, strict: NameIsInvalid)
|
508
|
+
# # => NameIsInvalid: Name is invalid
|
509
|
+
#
|
510
|
+
# person.errors.messages # => {}
|
511
|
+
# ```
|
512
|
+
#
|
513
|
+
# `attribute` should be set to `:base` if the error is not
|
514
|
+
# directly associated with a single attribute.
|
515
|
+
#
|
516
|
+
# ```ruby
|
517
|
+
# person.errors.add(:base, :name_or_email_blank,
|
518
|
+
# message: "either name or email must be present")
|
519
|
+
# person.errors.messages
|
520
|
+
# # => {:base=>["either name or email must be present"]}
|
521
|
+
# person.errors.details
|
522
|
+
# # => {:base=>[{error: :name_or_email_blank}]}
|
523
|
+
# ```
|
524
|
+
sig do
|
525
|
+
params(
|
526
|
+
attribute: Symbol,
|
527
|
+
message: T.any(String, Symbol),
|
528
|
+
options: T::Hash[T.untyped, T.untyped]
|
529
|
+
).returns(T.untyped)
|
530
|
+
end
|
531
|
+
def add(attribute, message = :invalid, options = {}); end
|
532
|
+
|
533
|
+
# Returns `true` if an error on the attribute with the given message is
|
534
|
+
# present, or `false` otherwise. `message` is treated the same as for `add`.
|
535
|
+
#
|
536
|
+
# ```ruby
|
537
|
+
# person.errors.add :name, :blank
|
538
|
+
# person.errors.added? :name, :blank # => true
|
539
|
+
# person.errors.added? :name, "can't be blank" # => true
|
540
|
+
# ```
|
541
|
+
#
|
542
|
+
# If the error message requires options, then it returns `true` with
|
543
|
+
# the correct options, or `false` with incorrect or missing options.
|
544
|
+
#
|
545
|
+
# ```ruby
|
546
|
+
# person.errors.add :name, :too_long, { count: 25 }
|
547
|
+
# person.errors.added? :name, :too_long, count: 25 # => true
|
548
|
+
# person.errors.added? :name, "is too long (maximum is 25 characters)" # => true
|
549
|
+
# person.errors.added? :name, :too_long, count: 24 # => false
|
550
|
+
# person.errors.added? :name, :too_long # => false
|
551
|
+
# person.errors.added? :name, "is too long" # => false
|
552
|
+
# ```
|
553
|
+
sig do
|
554
|
+
params(
|
555
|
+
attribute: Symbol,
|
556
|
+
message: T.any(String, Symbol),
|
557
|
+
options: T::Hash[T.untyped, T.untyped]
|
558
|
+
).returns(T::Boolean)
|
559
|
+
end
|
560
|
+
def added?(attribute, message = :invalid, options = {}); end
|
561
|
+
|
562
|
+
# Returns `true` if an error on the attribute with the given message is
|
563
|
+
# present, or `false` otherwise. `message` is treated the same as for `add`.
|
564
|
+
#
|
565
|
+
# ```ruby
|
566
|
+
# person.errors.add :age
|
567
|
+
# person.errors.add :name, :too_long, { count: 25 }
|
568
|
+
# person.errors.of_kind? :age # => true
|
569
|
+
# person.errors.of_kind? :name # => false
|
570
|
+
# person.errors.of_kind? :name, :too_long # => true
|
571
|
+
# person.errors.of_kind? :name, "is too long (maximum is 25 characters)" # => true
|
572
|
+
# person.errors.of_kind? :name, :not_too_long # => false
|
573
|
+
# person.errors.of_kind? :name, "is too long" # => false
|
574
|
+
# ```
|
575
|
+
sig do
|
576
|
+
params(
|
577
|
+
attribute: Symbol,
|
578
|
+
message: T.any(String, Symbol)
|
579
|
+
).returns(T::Boolean)
|
580
|
+
end
|
581
|
+
def of_kind?(attribute, message = :invalid); end
|
582
|
+
|
583
|
+
# Returns all the full error messages in an array.
|
584
|
+
#
|
585
|
+
# ```ruby
|
586
|
+
# class Person
|
587
|
+
# validates_presence_of :name, :address, :email
|
588
|
+
# validates_length_of :name, in: 5..30
|
589
|
+
# end
|
590
|
+
#
|
591
|
+
# person = Person.create(address: '123 First St.')
|
592
|
+
# person.errors.full_messages
|
593
|
+
# # => ["Name is too short (minimum is 5 characters)", "Name can't be blank", "Email can't be blank"]
|
594
|
+
# ```
|
595
|
+
sig { returns(T::Array[String]) }
|
596
|
+
def full_messages; end
|
597
|
+
end
|