rubocop-rails 2.6.0 → 2.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +16 -0
- data/config/default.yml +189 -6
- data/lib/rubocop/cop/mixin/active_record_helper.rb +12 -3
- data/lib/rubocop/cop/mixin/enforce_superclass.rb +40 -0
- data/lib/rubocop/cop/mixin/index_method.rb +25 -11
- data/lib/rubocop/cop/rails/action_filter.rb +10 -14
- data/lib/rubocop/cop/rails/active_record_aliases.rb +13 -17
- data/lib/rubocop/cop/rails/active_record_callbacks_order.rb +148 -0
- data/lib/rubocop/cop/rails/active_record_override.rb +1 -1
- data/lib/rubocop/cop/rails/active_support_aliases.rb +12 -21
- data/lib/rubocop/cop/rails/after_commit_override.rb +91 -0
- data/lib/rubocop/cop/rails/application_controller.rb +3 -7
- data/lib/rubocop/cop/rails/application_job.rb +2 -1
- data/lib/rubocop/cop/rails/application_mailer.rb +2 -7
- data/lib/rubocop/cop/rails/application_record.rb +2 -7
- data/lib/rubocop/cop/rails/arel_star.rb +41 -0
- data/lib/rubocop/cop/rails/assert_not.rb +8 -10
- data/lib/rubocop/cop/rails/attribute_default_block_value.rb +90 -0
- data/lib/rubocop/cop/rails/belongs_to.rb +9 -18
- data/lib/rubocop/cop/rails/blank.rb +27 -27
- data/lib/rubocop/cop/rails/bulk_change_table.rb +1 -1
- data/lib/rubocop/cop/rails/content_tag.rb +20 -33
- data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +2 -1
- data/lib/rubocop/cop/rails/date.rb +10 -11
- data/lib/rubocop/cop/rails/default_scope.rb +61 -0
- data/lib/rubocop/cop/rails/delegate.rb +10 -10
- data/lib/rubocop/cop/rails/delegate_allow_blank.rb +7 -8
- data/lib/rubocop/cop/rails/dynamic_find_by.rb +13 -11
- data/lib/rubocop/cop/rails/enum_hash.rb +11 -10
- data/lib/rubocop/cop/rails/enum_uniqueness.rb +2 -1
- data/lib/rubocop/cop/rails/environment_comparison.rb +18 -14
- data/lib/rubocop/cop/rails/exit.rb +4 -10
- data/lib/rubocop/cop/rails/file_path.rb +5 -4
- data/lib/rubocop/cop/rails/find_by.rb +13 -13
- data/lib/rubocop/cop/rails/find_by_id.rb +94 -0
- data/lib/rubocop/cop/rails/find_each.rb +16 -14
- data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +3 -2
- data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +4 -7
- data/lib/rubocop/cop/rails/helper_instance_variable.rb +4 -2
- data/lib/rubocop/cop/rails/http_positional_arguments.rb +25 -21
- data/lib/rubocop/cop/rails/http_status.rb +7 -9
- data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +8 -6
- data/lib/rubocop/cop/rails/index_by.rb +11 -2
- data/lib/rubocop/cop/rails/index_with.rb +11 -2
- data/lib/rubocop/cop/rails/inquiry.rb +39 -0
- data/lib/rubocop/cop/rails/inverse_of.rb +3 -2
- data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +17 -15
- data/lib/rubocop/cop/rails/link_to_blank.rb +20 -20
- data/lib/rubocop/cop/rails/mailer_name.rb +86 -0
- data/lib/rubocop/cop/rails/match_route.rb +120 -0
- data/lib/rubocop/cop/rails/negate_include.rb +41 -0
- data/lib/rubocop/cop/rails/not_null_column.rb +2 -1
- data/lib/rubocop/cop/rails/order_by_id.rb +52 -0
- data/lib/rubocop/cop/rails/output.rb +5 -2
- data/lib/rubocop/cop/rails/output_safety.rb +3 -2
- data/lib/rubocop/cop/rails/pick.rb +21 -15
- data/lib/rubocop/cop/rails/pluck.rb +56 -0
- data/lib/rubocop/cop/rails/pluck_id.rb +56 -0
- data/lib/rubocop/cop/rails/pluck_in_where.rb +70 -0
- data/lib/rubocop/cop/rails/pluralization_grammar.rb +10 -14
- data/lib/rubocop/cop/rails/presence.rb +12 -13
- data/lib/rubocop/cop/rails/present.rb +30 -24
- data/lib/rubocop/cop/rails/rake_environment.rb +9 -11
- data/lib/rubocop/cop/rails/read_write_attribute.rb +12 -11
- data/lib/rubocop/cop/rails/redundant_allow_nil.rb +29 -31
- data/lib/rubocop/cop/rails/redundant_foreign_key.rb +9 -12
- data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +11 -10
- data/lib/rubocop/cop/rails/reflection_class_name.rb +4 -3
- data/lib/rubocop/cop/rails/refute_methods.rb +9 -10
- data/lib/rubocop/cop/rails/relative_date_constant.rb +20 -9
- data/lib/rubocop/cop/rails/render_inline.rb +41 -0
- data/lib/rubocop/cop/rails/render_plain_text.rb +71 -0
- data/lib/rubocop/cop/rails/request_referer.rb +7 -7
- data/lib/rubocop/cop/rails/reversible_migration.rb +82 -7
- data/lib/rubocop/cop/rails/safe_navigation.rb +12 -11
- data/lib/rubocop/cop/rails/safe_navigation_with_blank.rb +5 -10
- data/lib/rubocop/cop/rails/save_bang.rb +19 -22
- data/lib/rubocop/cop/rails/scope_args.rb +2 -1
- data/lib/rubocop/cop/rails/short_i18n.rb +74 -0
- data/lib/rubocop/cop/rails/skips_model_validations.rb +46 -11
- data/lib/rubocop/cop/rails/squished_sql_heredocs.rb +82 -0
- data/lib/rubocop/cop/rails/time_zone.rb +22 -20
- data/lib/rubocop/cop/rails/uniq_before_pluck.rb +10 -10
- data/lib/rubocop/cop/rails/unique_validation_without_index.rb +18 -8
- data/lib/rubocop/cop/rails/unknown_env.rb +15 -4
- data/lib/rubocop/cop/rails/validation.rb +15 -14
- data/lib/rubocop/cop/rails/where_equals.rb +94 -0
- data/lib/rubocop/cop/rails/where_exists.rb +126 -0
- data/lib/rubocop/cop/rails/where_not.rb +97 -0
- data/lib/rubocop/cop/rails_cops.rb +22 -0
- data/lib/rubocop/rails/schema_loader.rb +4 -4
- data/lib/rubocop/rails/schema_loader/schema.rb +5 -5
- data/lib/rubocop/rails/version.rb +5 -1
- metadata +37 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b997fb5d9995a5c7db5d151e13b86cf0dbd2b27f890e9ad116d11fab30a1b7e0
|
4
|
+
data.tar.gz: 91c6b0a496bcbe9c92b0833944b301e893c9f9ee6e75db0fb393436c9869dc81
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d59f7cbb8d1f311bcdda8eda6c1c55d5cbc772993cac726f6d16d1947ca324b95354e24770140d3fce1a860cd2b4995d55c78e946c21ed85c9f4964b4d908794
|
7
|
+
data.tar.gz: 891fc8896d26423f80edd9db48e75c065c3e46ccb03a534f182dd3af928b19165e7d2d259cd842b1222a729ba4e234d461e370327db4bb520673ab61071e0e89
|
data/README.md
CHANGED
@@ -86,6 +86,22 @@ Rails cops support the following versions:
|
|
86
86
|
|
87
87
|
- Rails 4.2+
|
88
88
|
|
89
|
+
## Readme Badge
|
90
|
+
|
91
|
+
If you use RuboCop Rails in your project, you can include one of these badges in your readme to let people know that your code is written following the community Rails Style Guide.
|
92
|
+
|
93
|
+
[![Rails Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop-hq/rubocop-rails)
|
94
|
+
|
95
|
+
[![Rails Style Guide](https://img.shields.io/badge/code_style-community-brightgreen.svg)](https://rails.rubystyle.guide)
|
96
|
+
|
97
|
+
Here are the Markdown snippets for the two badges:
|
98
|
+
|
99
|
+
``` markdown
|
100
|
+
[![Rails Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop-hq/rubocop-rails)
|
101
|
+
|
102
|
+
[![Rails Style Guide](https://img.shields.io/badge/code_style-community-brightgreen.svg)](https://rails.rubystyle.guide)
|
103
|
+
```
|
104
|
+
|
89
105
|
## Contributing
|
90
106
|
|
91
107
|
Checkout the [contribution guidelines](CONTRIBUTING.md).
|
data/config/default.yml
CHANGED
@@ -37,6 +37,14 @@ Rails/ActiveRecordAliases:
|
|
37
37
|
VersionAdded: '0.53'
|
38
38
|
SafeAutoCorrect: false
|
39
39
|
|
40
|
+
Rails/ActiveRecordCallbacksOrder:
|
41
|
+
Description: 'Order callback declarations in the order in which they will be executed.'
|
42
|
+
StyleGuide: 'https://rails.rubystyle.guide/#callbacks-order'
|
43
|
+
Enabled: 'pending'
|
44
|
+
VersionAdded: '2.7'
|
45
|
+
Include:
|
46
|
+
- app/models/**/*.rb
|
47
|
+
|
40
48
|
Rails/ActiveRecordOverride:
|
41
49
|
Description: >-
|
42
50
|
Check for overriding Active Record methods instead of using
|
@@ -54,6 +62,14 @@ Rails/ActiveSupportAliases:
|
|
54
62
|
Enabled: true
|
55
63
|
VersionAdded: '0.48'
|
56
64
|
|
65
|
+
Rails/AfterCommitOverride:
|
66
|
+
Description: >-
|
67
|
+
This cop enforces that there is only one call to `after_commit`
|
68
|
+
(and its aliases - `after_create_commit`, `after_update_commit`,
|
69
|
+
and `after_destroy_commit`) with the same callback name per model.
|
70
|
+
Enabled: 'pending'
|
71
|
+
VersionAdded: '2.8'
|
72
|
+
|
57
73
|
Rails/ApplicationController:
|
58
74
|
Description: 'Check that controllers subclass ApplicationController.'
|
59
75
|
Enabled: true
|
@@ -82,6 +98,12 @@ Rails/ApplicationRecord:
|
|
82
98
|
VersionAdded: '0.49'
|
83
99
|
VersionChanged: '2.5'
|
84
100
|
|
101
|
+
Rails/ArelStar:
|
102
|
+
Description: 'Enforces `Arel.star` instead of `"*"` for expanded columns.'
|
103
|
+
Enabled: true
|
104
|
+
SafeAutoCorrect: false
|
105
|
+
VersionAdded: '2.9'
|
106
|
+
|
85
107
|
Rails/AssertNot:
|
86
108
|
Description: 'Use `assert_not` instead of `assert !`.'
|
87
109
|
Enabled: true
|
@@ -89,6 +111,13 @@ Rails/AssertNot:
|
|
89
111
|
Include:
|
90
112
|
- '**/test/**/*'
|
91
113
|
|
114
|
+
Rails/AttributeDefaultBlockValue:
|
115
|
+
Description: 'Pass method call in block for attribute option `default`.'
|
116
|
+
Enabled: pending
|
117
|
+
VersionAdded: '2.9'
|
118
|
+
Include:
|
119
|
+
- 'models/**/*'
|
120
|
+
|
92
121
|
Rails/BelongsTo:
|
93
122
|
Description: >-
|
94
123
|
Use `optional: true` instead of `required: false` for
|
@@ -153,6 +182,12 @@ Rails/Date:
|
|
153
182
|
- strict
|
154
183
|
- flexible
|
155
184
|
|
185
|
+
Rails/DefaultScope:
|
186
|
+
Description: 'Avoid use of `default_scope`.'
|
187
|
+
StyleGuide: 'https://rails.rubystyle.guide#avoid-default-scope'
|
188
|
+
Enabled: false
|
189
|
+
VersionAdded: '2.7'
|
190
|
+
|
156
191
|
Rails/Delegate:
|
157
192
|
Description: 'Prefer delegate method for delegations.'
|
158
193
|
Enabled: true
|
@@ -234,13 +269,28 @@ Rails/FindBy:
|
|
234
269
|
Include:
|
235
270
|
- app/models/**/*.rb
|
236
271
|
|
272
|
+
Rails/FindById:
|
273
|
+
Description: >-
|
274
|
+
Favor the use of `find` over `where.take!`, `find_by!`, and `find_by_id!` when you
|
275
|
+
need to retrieve a single record by primary key when you expect it to be found.
|
276
|
+
StyleGuide: 'https://rails.rubystyle.guide/#find'
|
277
|
+
Enabled: 'pending'
|
278
|
+
VersionAdded: '2.7'
|
279
|
+
|
237
280
|
Rails/FindEach:
|
238
281
|
Description: 'Prefer all.find_each over all.find.'
|
239
282
|
StyleGuide: 'https://rails.rubystyle.guide#find-each'
|
240
283
|
Enabled: true
|
241
284
|
VersionAdded: '0.30'
|
285
|
+
VersionChanged: '2.9'
|
242
286
|
Include:
|
243
287
|
- app/models/**/*.rb
|
288
|
+
IgnoredMethods:
|
289
|
+
# Methods that don't work well with `find_each`.
|
290
|
+
- order
|
291
|
+
- limit
|
292
|
+
- select
|
293
|
+
- lock
|
244
294
|
|
245
295
|
Rails/HasAndBelongsToMany:
|
246
296
|
Description: 'Prefer has_many :through to has_and_belongs_to_many.'
|
@@ -291,14 +341,22 @@ Rails/IgnoredSkipActionFilterOption:
|
|
291
341
|
- app/controllers/**/*.rb
|
292
342
|
|
293
343
|
Rails/IndexBy:
|
294
|
-
Description: 'Prefer `index_by` over `each_with_object` or `map`.'
|
344
|
+
Description: 'Prefer `index_by` over `each_with_object`, `to_h`, or `map`.'
|
295
345
|
Enabled: true
|
296
346
|
VersionAdded: '2.5'
|
347
|
+
VersionChanged: '2.8'
|
297
348
|
|
298
349
|
Rails/IndexWith:
|
299
|
-
Description: 'Prefer `index_with` over `each_with_object` or `map`.'
|
350
|
+
Description: 'Prefer `index_with` over `each_with_object`, `to_h`, or `map`.'
|
300
351
|
Enabled: true
|
301
352
|
VersionAdded: '2.5'
|
353
|
+
VersionChanged: '2.8'
|
354
|
+
|
355
|
+
Rails/Inquiry:
|
356
|
+
Description: "Prefer Ruby's comparison operators over Active Support's `Array#inquiry` and `String#inquiry`."
|
357
|
+
StyleGuide: 'https://rails.rubystyle.guide/#inquiry'
|
358
|
+
Enabled: 'pending'
|
359
|
+
VersionAdded: '2.7'
|
302
360
|
|
303
361
|
Rails/InverseOf:
|
304
362
|
Description: 'Checks for associations where the inverse cannot be determined automatically.'
|
@@ -325,6 +383,34 @@ Rails/LinkToBlank:
|
|
325
383
|
Enabled: true
|
326
384
|
VersionAdded: '0.62'
|
327
385
|
|
386
|
+
Rails/MailerName:
|
387
|
+
Description: 'Mailer should end with `Mailer` suffix.'
|
388
|
+
StyleGuide: 'https://rails.rubystyle.guide/#mailer-name'
|
389
|
+
Enabled: 'pending'
|
390
|
+
SafeAutoCorrect: false
|
391
|
+
VersionAdded: '2.7'
|
392
|
+
Include:
|
393
|
+
- app/mailers/**/*.rb
|
394
|
+
|
395
|
+
Rails/MatchRoute:
|
396
|
+
Description: >-
|
397
|
+
Don't use `match` to define any routes unless there is a need to map multiple request types
|
398
|
+
among [:get, :post, :patch, :put, :delete] to a single action using the `:via` option.
|
399
|
+
StyleGuide: 'https://rails.rubystyle.guide/#no-match-routes'
|
400
|
+
Enabled: 'pending'
|
401
|
+
VersionAdded: '2.7'
|
402
|
+
Include:
|
403
|
+
- config/routes.rb
|
404
|
+
- config/routes/**/*.rb
|
405
|
+
|
406
|
+
Rails/NegateInclude:
|
407
|
+
Description: 'Prefer `collection.exclude?(obj)` over `!collection.include?(obj)`.'
|
408
|
+
StyleGuide: 'https://rails.rubystyle.guide#exclude'
|
409
|
+
Enabled: 'pending'
|
410
|
+
Safe: false
|
411
|
+
VersionAdded: '2.7'
|
412
|
+
VersionChanged: '2.9'
|
413
|
+
|
328
414
|
Rails/NotNullColumn:
|
329
415
|
Description: 'Do not add a NOT NULL column without a default value.'
|
330
416
|
Enabled: true
|
@@ -332,6 +418,14 @@ Rails/NotNullColumn:
|
|
332
418
|
Include:
|
333
419
|
- db/migrate/*.rb
|
334
420
|
|
421
|
+
Rails/OrderById:
|
422
|
+
Description: >-
|
423
|
+
Do not use the `id` column for ordering.
|
424
|
+
Use a timestamp column to order chronologically.
|
425
|
+
StyleGuide: 'https://rails.rubystyle.guide/#order-by-id'
|
426
|
+
Enabled: false
|
427
|
+
VersionAdded: '2.8'
|
428
|
+
|
335
429
|
Rails/Output:
|
336
430
|
Description: 'Checks for calls to puts, print, etc.'
|
337
431
|
Enabled: true
|
@@ -350,10 +444,35 @@ Rails/OutputSafety:
|
|
350
444
|
|
351
445
|
Rails/Pick:
|
352
446
|
Description: 'Prefer `pick` over `pluck(...).first`.'
|
447
|
+
StyleGuide: 'https://rails.rubystyle.guide#pick'
|
353
448
|
Enabled: true
|
354
449
|
Safe: false
|
355
450
|
VersionAdded: '2.6'
|
356
451
|
|
452
|
+
Rails/Pluck:
|
453
|
+
Description: 'Prefer `pluck` over `map { ... }`.'
|
454
|
+
StyleGuide: 'https://rails.rubystyle.guide#pluck'
|
455
|
+
Enabled: 'pending'
|
456
|
+
VersionAdded: '2.7'
|
457
|
+
|
458
|
+
Rails/PluckId:
|
459
|
+
Description: 'Use `ids` instead of `pluck(:id)` or `pluck(primary_key)`.'
|
460
|
+
StyleGuide: 'https://rails.rubystyle.guide/#ids'
|
461
|
+
Enabled: false
|
462
|
+
Safe: false
|
463
|
+
VersionAdded: '2.7'
|
464
|
+
|
465
|
+
Rails/PluckInWhere:
|
466
|
+
Description: 'Use `select` instead of `pluck` in `where` query methods.'
|
467
|
+
Enabled: 'pending'
|
468
|
+
Safe: false
|
469
|
+
VersionAdded: '2.7'
|
470
|
+
VersionChanged: '2.8'
|
471
|
+
EnforcedStyle: conservative
|
472
|
+
SupportedStyles:
|
473
|
+
- conservative
|
474
|
+
- aggressive
|
475
|
+
|
357
476
|
Rails/PluralizationGrammar:
|
358
477
|
Description: 'Checks for incorrect grammar when using methods like `3.day.ago`.'
|
359
478
|
Enabled: true
|
@@ -441,6 +560,20 @@ Rails/RelativeDateConstant:
|
|
441
560
|
VersionChanged: '0.59'
|
442
561
|
AutoCorrect: false
|
443
562
|
|
563
|
+
Rails/RenderInline:
|
564
|
+
Description: 'Prefer using a template over inline rendering.'
|
565
|
+
StyleGuide: 'https://rails.rubystyle.guide/#inline-rendering'
|
566
|
+
Enabled: 'pending'
|
567
|
+
VersionAdded: '2.7'
|
568
|
+
|
569
|
+
Rails/RenderPlainText:
|
570
|
+
Description: 'Prefer `render plain:` over `render text:`.'
|
571
|
+
StyleGuide: 'https://rails.rubystyle.guide/#plain-text-rendering'
|
572
|
+
Enabled: 'pending'
|
573
|
+
VersionAdded: '2.7'
|
574
|
+
# Convert only when `content_type` is explicitly set to `text/plain`.
|
575
|
+
ContentTypeCompatibility: true
|
576
|
+
|
444
577
|
Rails/RequestReferer:
|
445
578
|
Description: 'Use consistent syntax for request.referer.'
|
446
579
|
Enabled: true
|
@@ -498,6 +631,16 @@ Rails/ScopeArgs:
|
|
498
631
|
Include:
|
499
632
|
- app/models/**/*.rb
|
500
633
|
|
634
|
+
Rails/ShortI18n:
|
635
|
+
Description: 'Use the short form of the I18n methods: `t` instead of `translate` and `l` instead of `localize`.'
|
636
|
+
StyleGuide: 'https://rails.rubystyle.guide/#short-i18n'
|
637
|
+
Enabled: 'pending'
|
638
|
+
VersionAdded: '2.7'
|
639
|
+
EnforcedStyle: conservative
|
640
|
+
SupportedStyles:
|
641
|
+
- conservative
|
642
|
+
- aggressive
|
643
|
+
|
501
644
|
Rails/SkipsModelValidations:
|
502
645
|
Description: >-
|
503
646
|
Use methods that skips model validations with caution.
|
@@ -505,20 +648,37 @@ Rails/SkipsModelValidations:
|
|
505
648
|
Reference: 'https://guides.rubyonrails.org/active_record_validations.html#skipping-validations'
|
506
649
|
Enabled: true
|
507
650
|
VersionAdded: '0.47'
|
508
|
-
VersionChanged: '
|
509
|
-
|
651
|
+
VersionChanged: '2.7'
|
652
|
+
ForbiddenMethods:
|
510
653
|
- decrement!
|
511
654
|
- decrement_counter
|
512
655
|
- increment!
|
513
656
|
- increment_counter
|
657
|
+
- insert
|
658
|
+
- insert!
|
659
|
+
- insert_all
|
660
|
+
- insert_all!
|
514
661
|
- toggle!
|
515
662
|
- touch
|
663
|
+
- touch_all
|
516
664
|
- update_all
|
517
665
|
- update_attribute
|
518
666
|
- update_column
|
519
667
|
- update_columns
|
520
668
|
- update_counters
|
521
|
-
|
669
|
+
- upsert
|
670
|
+
- upsert_all
|
671
|
+
AllowedMethods: []
|
672
|
+
|
673
|
+
Rails/SquishedSQLHeredocs:
|
674
|
+
Description: 'Checks SQL heredocs to use `.squish`.'
|
675
|
+
StyleGuide: 'https://rails.rubystyle.guide/#squished-heredocs'
|
676
|
+
Enabled: 'pending'
|
677
|
+
VersionAdded: '2.8'
|
678
|
+
VersionChanged: '2.9'
|
679
|
+
# Some SQL syntax (e.g. PostgreSQL comments and functions) requires newlines
|
680
|
+
# to be preserved in order to work, thus auto-correction is not safe.
|
681
|
+
SafeAutoCorrect: false
|
522
682
|
|
523
683
|
Rails/TimeZone:
|
524
684
|
Description: 'Checks the correct usage of time zone aware methods.'
|
@@ -539,11 +699,12 @@ Rails/UniqBeforePluck:
|
|
539
699
|
Description: 'Prefer the use of uniq or distinct before pluck.'
|
540
700
|
Enabled: true
|
541
701
|
VersionAdded: '0.40'
|
542
|
-
VersionChanged: '2.
|
702
|
+
VersionChanged: '2.8'
|
543
703
|
EnforcedStyle: conservative
|
544
704
|
SupportedStyles:
|
545
705
|
- conservative
|
546
706
|
- aggressive
|
707
|
+
SafeAutoCorrect: false
|
547
708
|
AutoCorrect: false
|
548
709
|
|
549
710
|
Rails/UniqueValidationWithoutIndex:
|
@@ -570,6 +731,28 @@ Rails/Validation:
|
|
570
731
|
Include:
|
571
732
|
- app/models/**/*.rb
|
572
733
|
|
734
|
+
Rails/WhereEquals:
|
735
|
+
Description: 'Pass conditions to `where` as a hash instead of manually constructing SQL.'
|
736
|
+
StyleGuide: 'https://rails.rubystyle.guide/#hash-conditions'
|
737
|
+
Enabled: 'pending'
|
738
|
+
VersionAdded: '2.9'
|
739
|
+
|
740
|
+
Rails/WhereExists:
|
741
|
+
Description: 'Prefer `exists?(...)` over `where(...).exists?`.'
|
742
|
+
Enabled: 'pending'
|
743
|
+
EnforcedStyle: exists
|
744
|
+
SupportedStyles:
|
745
|
+
- exists
|
746
|
+
- where
|
747
|
+
VersionAdded: '2.7'
|
748
|
+
VersionChanged: '2.8'
|
749
|
+
|
750
|
+
Rails/WhereNot:
|
751
|
+
Description: 'Use `where.not(...)` instead of manually constructing negated SQL in `where`.'
|
752
|
+
StyleGuide: 'https://rails.rubystyle.guide/#hash-conditions'
|
753
|
+
Enabled: 'pending'
|
754
|
+
VersionAdded: '2.8'
|
755
|
+
|
573
756
|
# Accept `redirect_to(...) and return` and similar cases.
|
574
757
|
Style/AndOr:
|
575
758
|
EnforcedStyle: conditionals
|
@@ -6,6 +6,8 @@ module RuboCop
|
|
6
6
|
module ActiveRecordHelper
|
7
7
|
extend NodePattern::Macros
|
8
8
|
|
9
|
+
WHERE_METHODS = %i[where rewhere].freeze
|
10
|
+
|
9
11
|
def_node_search :find_set_table_name, <<~PATTERN
|
10
12
|
(send self :table_name= {str sym})
|
11
13
|
PATTERN
|
@@ -33,10 +35,11 @@ module RuboCop
|
|
33
35
|
table_name = find_set_table_name(class_node).to_a.last&.first_argument
|
34
36
|
return table_name.value.to_s if table_name
|
35
37
|
|
36
|
-
|
37
|
-
|
38
|
+
class_nodes = class_node.defined_module.each_node
|
39
|
+
namespaces = class_node.each_ancestor(:class, :module).map(&:identifier)
|
40
|
+
[*class_nodes, *namespaces]
|
38
41
|
.reverse
|
39
|
-
.map { |
|
42
|
+
.map { |node| node.children[1] }.join('_')
|
40
43
|
.tableize
|
41
44
|
end
|
42
45
|
|
@@ -50,6 +53,7 @@ module RuboCop
|
|
50
53
|
# @param table [RuboCop::Rails::SchemaLoader::Table]
|
51
54
|
# @return [String, nil]
|
52
55
|
def resolve_relation_into_column(name:, class_node:, table:)
|
56
|
+
return unless table
|
53
57
|
return name if table.with_column?(name: name)
|
54
58
|
|
55
59
|
find_belongs_to(class_node) do |belongs_to|
|
@@ -72,6 +76,11 @@ module RuboCop
|
|
72
76
|
break pair.value.value.to_s
|
73
77
|
end
|
74
78
|
end
|
79
|
+
|
80
|
+
def in_where?(node)
|
81
|
+
send_node = node.each_ancestor(:send).first
|
82
|
+
send_node && WHERE_METHODS.include?(send_node.method_name)
|
83
|
+
end
|
75
84
|
end
|
76
85
|
end
|
77
86
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# Common functionality for enforcing a specific superclass.
|
6
|
+
module EnforceSuperclass
|
7
|
+
def self.included(base)
|
8
|
+
base.def_node_matcher :class_definition, <<~PATTERN
|
9
|
+
(class (const _ !:#{base::SUPERCLASS}) #{base::BASE_PATTERN} ...)
|
10
|
+
PATTERN
|
11
|
+
|
12
|
+
base.def_node_matcher :class_new_definition, <<~PATTERN
|
13
|
+
[!^(casgn {nil? cbase} :#{base::SUPERCLASS} ...)
|
14
|
+
!^^(casgn {nil? cbase} :#{base::SUPERCLASS} (block ...))
|
15
|
+
(send (const {nil? cbase} :Class) :new #{base::BASE_PATTERN})]
|
16
|
+
PATTERN
|
17
|
+
end
|
18
|
+
|
19
|
+
def on_class(node)
|
20
|
+
class_definition(node) do
|
21
|
+
register_offense(node.children[1])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def on_send(node)
|
26
|
+
class_new_definition(node) do
|
27
|
+
register_offense(node.children.last)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def register_offense(offense_node)
|
34
|
+
add_offense(offense_node) do |corrector|
|
35
|
+
corrector.replace(offense_node.source_range, self.class::SUPERCLASS)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -4,10 +4,18 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
# Common functionality for Rails/IndexBy and Rails/IndexWith
|
6
6
|
module IndexMethod # rubocop:disable Metrics/ModuleLength
|
7
|
+
RESTRICT_ON_SEND = %i[each_with_object to_h map collect []].freeze
|
8
|
+
|
7
9
|
def on_block(node)
|
8
10
|
on_bad_each_with_object(node) do |*match|
|
9
11
|
handle_possible_offense(node, match, 'each_with_object')
|
10
12
|
end
|
13
|
+
|
14
|
+
return if target_ruby_version < 2.6
|
15
|
+
|
16
|
+
on_bad_to_h(node) do |*match|
|
17
|
+
handle_possible_offense(node, match, 'to_h { ... }')
|
18
|
+
end
|
11
19
|
end
|
12
20
|
|
13
21
|
def on_send(node)
|
@@ -26,13 +34,6 @@ module RuboCop
|
|
26
34
|
end
|
27
35
|
end
|
28
36
|
|
29
|
-
def autocorrect(node)
|
30
|
-
lambda do |corrector|
|
31
|
-
correction = prepare_correction(node)
|
32
|
-
execute_correction(corrector, node, correction)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
37
|
private
|
37
38
|
|
38
39
|
# @abstract Implemented with `def_node_matcher`
|
@@ -40,6 +41,11 @@ module RuboCop
|
|
40
41
|
raise NotImplementedError
|
41
42
|
end
|
42
43
|
|
44
|
+
# @abstract Implemented with `def_node_matcher`
|
45
|
+
def on_bad_to_h(_node)
|
46
|
+
raise NotImplementedError
|
47
|
+
end
|
48
|
+
|
43
49
|
# @abstract Implemented with `def_node_matcher`
|
44
50
|
def on_bad_map_to_h(_node)
|
45
51
|
raise NotImplementedError
|
@@ -56,9 +62,11 @@ module RuboCop
|
|
56
62
|
return if captures.noop_transformation?
|
57
63
|
|
58
64
|
add_offense(
|
59
|
-
node,
|
60
|
-
|
61
|
-
|
65
|
+
node, message: "Prefer `#{new_method_name}` over `#{match_desc}`."
|
66
|
+
) do |corrector|
|
67
|
+
correction = prepare_correction(node)
|
68
|
+
execute_correction(corrector, node, correction)
|
69
|
+
end
|
62
70
|
end
|
63
71
|
|
64
72
|
def extract_captures(match)
|
@@ -73,6 +81,8 @@ module RuboCop
|
|
73
81
|
def prepare_correction(node)
|
74
82
|
if (match = on_bad_each_with_object(node))
|
75
83
|
Autocorrection.from_each_with_object(node, match)
|
84
|
+
elsif (match = on_bad_to_h(node))
|
85
|
+
Autocorrection.from_to_h(node, match)
|
76
86
|
elsif (match = on_bad_map_to_h(node))
|
77
87
|
Autocorrection.from_map_to_h(node, match)
|
78
88
|
elsif (match = on_bad_hash_brackets_map(node))
|
@@ -106,11 +116,15 @@ module RuboCop
|
|
106
116
|
end
|
107
117
|
|
108
118
|
# Internal helper class to hold autocorrect data
|
109
|
-
Autocorrection = Struct.new(:match, :block_node, :leading, :trailing) do
|
119
|
+
Autocorrection = Struct.new(:match, :block_node, :leading, :trailing) do
|
110
120
|
def self.from_each_with_object(node, match)
|
111
121
|
new(match, node, 0, 0)
|
112
122
|
end
|
113
123
|
|
124
|
+
def self.from_to_h(node, match)
|
125
|
+
new(match, node, 0, 0)
|
126
|
+
end
|
127
|
+
|
114
128
|
def self.from_map_to_h(node, match)
|
115
129
|
strip_trailing_chars = 0
|
116
130
|
|