lazy_migrate 0.1.1 → 0.3.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.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/tests.yaml +43 -0
  3. data/.gitignore +4 -0
  4. data/.travis.yml +6 -0
  5. data/Appraisals +14 -0
  6. data/Gemfile.lock +150 -5
  7. data/Guardfile +39 -0
  8. data/README.md +56 -6
  9. data/Rakefile +1 -3
  10. data/bin/exe/lazy_migrate +14 -1
  11. data/gemfiles/.bundle/config +2 -0
  12. data/gemfiles/rails_5_1_5.gemfile +8 -0
  13. data/gemfiles/rails_5_1_5.gemfile.lock +170 -0
  14. data/gemfiles/rails_5_2_4_3.gemfile +8 -0
  15. data/gemfiles/rails_5_2_4_3.gemfile.lock +178 -0
  16. data/gemfiles/rails_6_0_3_4.gemfile +8 -0
  17. data/gemfiles/rails_6_0_3_4.gemfile.lock +194 -0
  18. data/github/demo.gif +0 -0
  19. data/lazy_migrate.gemspec +8 -2
  20. data/lib/lazy_migrate.rb +6 -2
  21. data/lib/lazy_migrate/client.rb +123 -0
  22. data/lib/lazy_migrate/migration.rb +14 -0
  23. data/lib/lazy_migrate/migrator_adapter.rb +144 -0
  24. data/lib/lazy_migrate/migrator_adapter_factory.rb +24 -0
  25. data/lib/lazy_migrate/new_migrator_adapter.rb +90 -0
  26. data/lib/lazy_migrate/old_migrator_adapter.rb +97 -0
  27. data/lib/lazy_migrate/version.rb +2 -1
  28. data/lib/tasks/lazy_migrate.rake +10 -0
  29. data/sorbet/config +2 -0
  30. data/sorbet/rbi/gems/actioncable.rbi +393 -0
  31. data/sorbet/rbi/gems/actionmailer.rbi +425 -0
  32. data/sorbet/rbi/gems/actionpack.rbi +3230 -0
  33. data/sorbet/rbi/gems/actionview.rbi +1153 -0
  34. data/sorbet/rbi/gems/activejob.rbi +282 -0
  35. data/sorbet/rbi/gems/activemodel.rbi +742 -0
  36. data/sorbet/rbi/gems/activerecord.rbi +4004 -0
  37. data/sorbet/rbi/gems/activestorage.rbi +174 -0
  38. data/sorbet/rbi/gems/activesupport.rbi +2300 -0
  39. data/sorbet/rbi/gems/appraisal.rbi +151 -0
  40. data/sorbet/rbi/gems/arel.rbi +1253 -0
  41. data/sorbet/rbi/gems/byebug.rbi +1041 -0
  42. data/sorbet/rbi/gems/coderay.rbi +92 -0
  43. data/sorbet/rbi/gems/concurrent-ruby.rbi +1586 -0
  44. data/sorbet/rbi/gems/crass.rbi +93 -0
  45. data/sorbet/rbi/gems/erubi.rbi +27 -0
  46. data/sorbet/rbi/gems/globalid.rbi +99 -0
  47. data/sorbet/rbi/gems/i18n.rbi +192 -0
  48. data/sorbet/rbi/gems/loofah.rbi +131 -0
  49. data/sorbet/rbi/gems/mail.rbi +1092 -0
  50. data/sorbet/rbi/gems/marcel.rbi +13 -0
  51. data/sorbet/rbi/gems/method_source.rbi +64 -0
  52. data/sorbet/rbi/gems/mini_mime.rbi +52 -0
  53. data/sorbet/rbi/gems/minitest.rbi +282 -0
  54. data/sorbet/rbi/gems/nio4r.rbi +68 -0
  55. data/sorbet/rbi/gems/nokogiri.rbi +1011 -0
  56. data/sorbet/rbi/gems/pastel.rbi +119 -0
  57. data/sorbet/rbi/gems/pry-byebug.rbi +155 -0
  58. data/sorbet/rbi/gems/pry.rbi +1949 -0
  59. data/sorbet/rbi/gems/rack-test.rbi +162 -0
  60. data/sorbet/rbi/gems/rack.rbi +525 -0
  61. data/sorbet/rbi/gems/rails-dom-testing.rbi +68 -0
  62. data/sorbet/rbi/gems/rails-html-sanitizer.rbi +92 -0
  63. data/sorbet/rbi/gems/railties.rbi +724 -0
  64. data/sorbet/rbi/gems/rake.rbi +666 -0
  65. data/sorbet/rbi/gems/rspec-core.rbi +1939 -0
  66. data/sorbet/rbi/gems/rspec-expectations.rbi +1123 -0
  67. data/sorbet/rbi/gems/rspec-mocks.rbi +1090 -0
  68. data/sorbet/rbi/gems/rspec-support.rbi +280 -0
  69. data/sorbet/rbi/gems/rspec.rbi +15 -0
  70. data/sorbet/rbi/gems/sprockets-rails.rbi +106 -0
  71. data/sorbet/rbi/gems/sprockets.rbi +755 -0
  72. data/sorbet/rbi/gems/sqlite3.rbi +354 -0
  73. data/sorbet/rbi/gems/thor.rbi +580 -0
  74. data/sorbet/rbi/gems/thread_safe.rbi +82 -0
  75. data/sorbet/rbi/gems/tty-color.rbi +44 -0
  76. data/sorbet/rbi/gems/tty-cursor.rbi +72 -0
  77. data/sorbet/rbi/gems/tty-prompt.rbi +531 -0
  78. data/sorbet/rbi/gems/tty-reader.rbi +176 -0
  79. data/sorbet/rbi/gems/tty-screen.rbi +66 -0
  80. data/sorbet/rbi/gems/tzinfo.rbi +406 -0
  81. data/sorbet/rbi/gems/websocket-driver.rbi +103 -0
  82. data/sorbet/rbi/gems/websocket-extensions.rbi +29 -0
  83. data/sorbet/rbi/gems/wisper.rbi +130 -0
  84. data/sorbet/rbi/hidden-definitions/errors.txt +7584 -0
  85. data/sorbet/rbi/hidden-definitions/hidden.rbi +13328 -0
  86. data/sorbet/rbi/sorbet-typed/lib/actionmailer/all/actionmailer.rbi +13 -0
  87. data/sorbet/rbi/sorbet-typed/lib/actionpack/all/actionpack.rbi +954 -0
  88. data/sorbet/rbi/sorbet-typed/lib/actionview/all/actionview.rbi +321 -0
  89. data/sorbet/rbi/sorbet-typed/lib/activemodel/all/activemodel.rbi +597 -0
  90. data/sorbet/rbi/sorbet-typed/lib/activerecord/<6/activerecord.rbi +13 -0
  91. data/sorbet/rbi/sorbet-typed/lib/activerecord/>=5.2/activerecord.rbi +16 -0
  92. data/sorbet/rbi/sorbet-typed/lib/activerecord/>=5/activerecord.rbi +53 -0
  93. data/sorbet/rbi/sorbet-typed/lib/activerecord/all/activerecord.rbi +1454 -0
  94. data/sorbet/rbi/sorbet-typed/lib/activerecord/all/model_schema.rbi +79 -0
  95. data/sorbet/rbi/sorbet-typed/lib/activerecord/all/sanitization.rbi +36 -0
  96. data/sorbet/rbi/sorbet-typed/lib/activerecord/~>5.2.0/activerecord.rbi +447 -0
  97. data/sorbet/rbi/sorbet-typed/lib/activestorage/<=6.1/activestorage.rbi +82 -0
  98. data/sorbet/rbi/sorbet-typed/lib/activestorage/all/activestorage.rbi +177 -0
  99. data/sorbet/rbi/sorbet-typed/lib/activesupport/all/activesupport.rbi +1431 -0
  100. data/sorbet/rbi/sorbet-typed/lib/minitest/all/minitest.rbi +108 -0
  101. data/sorbet/rbi/sorbet-typed/lib/railties/all/railties.rbi +25 -0
  102. data/sorbet/rbi/todo.rbi +18 -0
  103. data/sorbet/rbi/user-defined/activerecord.rbi +56 -0
  104. metadata +182 -5
  105. 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&amp;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