rubocop-rails 2.4.2 → 2.7.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/LICENSE.txt +1 -1
- data/README.md +5 -1
- data/config/default.yml +179 -9
- data/lib/rubocop-rails.rb +3 -0
- data/lib/rubocop/cop/mixin/active_record_helper.rb +84 -0
- data/lib/rubocop/cop/mixin/index_method.rb +161 -0
- data/lib/rubocop/cop/rails/active_record_callbacks_order.rb +145 -0
- data/lib/rubocop/cop/rails/content_tag.rb +69 -0
- data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +1 -3
- data/lib/rubocop/cop/rails/default_scope.rb +54 -0
- data/lib/rubocop/cop/rails/delegate.rb +2 -4
- data/lib/rubocop/cop/rails/dynamic_find_by.rb +40 -15
- data/lib/rubocop/cop/rails/environment_comparison.rb +60 -14
- data/lib/rubocop/cop/rails/exit.rb +2 -2
- data/lib/rubocop/cop/rails/file_path.rb +2 -1
- data/lib/rubocop/cop/rails/find_by_id.rb +103 -0
- data/lib/rubocop/cop/rails/http_positional_arguments.rb +2 -2
- data/lib/rubocop/cop/rails/http_status.rb +2 -0
- data/lib/rubocop/cop/rails/index_by.rb +56 -0
- data/lib/rubocop/cop/rails/index_with.rb +59 -0
- data/lib/rubocop/cop/rails/inquiry.rb +34 -0
- data/lib/rubocop/cop/rails/inverse_of.rb +0 -4
- data/lib/rubocop/cop/rails/link_to_blank.rb +3 -3
- data/lib/rubocop/cop/rails/mailer_name.rb +80 -0
- data/lib/rubocop/cop/rails/match_route.rb +117 -0
- data/lib/rubocop/cop/rails/negate_include.rb +39 -0
- data/lib/rubocop/cop/rails/pick.rb +55 -0
- data/lib/rubocop/cop/rails/pluck.rb +59 -0
- data/lib/rubocop/cop/rails/pluck_id.rb +58 -0
- data/lib/rubocop/cop/rails/pluck_in_where.rb +36 -0
- data/lib/rubocop/cop/rails/presence.rb +2 -6
- data/lib/rubocop/cop/rails/rake_environment.rb +17 -0
- data/lib/rubocop/cop/rails/redundant_foreign_key.rb +80 -0
- data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +0 -3
- data/lib/rubocop/cop/rails/refute_methods.rb +52 -26
- data/lib/rubocop/cop/rails/render_inline.rb +48 -0
- data/lib/rubocop/cop/rails/render_plain_text.rb +76 -0
- data/lib/rubocop/cop/rails/reversible_migration.rb +6 -1
- data/lib/rubocop/cop/rails/safe_navigation.rb +1 -1
- data/lib/rubocop/cop/rails/save_bang.rb +6 -7
- data/lib/rubocop/cop/rails/short_i18n.rb +76 -0
- data/lib/rubocop/cop/rails/skips_model_validations.rb +46 -8
- data/lib/rubocop/cop/rails/time_zone.rb +1 -3
- data/lib/rubocop/cop/rails/uniq_before_pluck.rb +12 -12
- data/lib/rubocop/cop/rails/unique_validation_without_index.rb +155 -0
- data/lib/rubocop/cop/rails/unknown_env.rb +7 -6
- data/lib/rubocop/cop/rails/where_exists.rb +68 -0
- data/lib/rubocop/cop/rails_cops.rb +22 -0
- data/lib/rubocop/rails/schema_loader.rb +61 -0
- data/lib/rubocop/rails/schema_loader/schema.rb +190 -0
- data/lib/rubocop/rails/version.rb +1 -1
- metadata +46 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a83fc9ded75b4055903b32234c6c9b878e76b22ee64b7e0d88cf2f54ac690d5
|
4
|
+
data.tar.gz: cb9cbde85b8117645e16c66d1670cffc61893eba8b5d5e3f530e7e42d81b147f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9df513d510b7a71d81bcf655088528ca642599702eca3f20d83eac18adcc15a3d2ab277760b78b9f86fc90df474409eaee454c6857623a2f459304fb74fdde00
|
7
|
+
data.tar.gz: 252a9b09c51b33b4ff53454fcc6ccaec41e719c283939475e643074305221a33652a9ab5649b9b2c51f36784bb67eeef5dbceee9b3852de936fed78073241dc0
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -76,11 +76,15 @@ Rails/FindBy:
|
|
76
76
|
- lib/example.rb
|
77
77
|
```
|
78
78
|
|
79
|
+
## Documentation
|
80
|
+
|
81
|
+
You can read a lot more about RuboCop Rails in its [official docs](https://docs.rubocop.org/rubocop-rails/).
|
82
|
+
|
79
83
|
## Compatibility
|
80
84
|
|
81
85
|
Rails cops support the following versions:
|
82
86
|
|
83
|
-
- Rails 4.
|
87
|
+
- Rails 4.2+
|
84
88
|
|
85
89
|
## Contributing
|
86
90
|
|
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
|
@@ -57,22 +65,30 @@ Rails/ActiveSupportAliases:
|
|
57
65
|
Rails/ApplicationController:
|
58
66
|
Description: 'Check that controllers subclass ApplicationController.'
|
59
67
|
Enabled: true
|
68
|
+
SafeAutoCorrect: false
|
60
69
|
VersionAdded: '2.4'
|
70
|
+
VersionChanged: '2.5'
|
61
71
|
|
62
72
|
Rails/ApplicationJob:
|
63
73
|
Description: 'Check that jobs subclass ApplicationJob.'
|
64
74
|
Enabled: true
|
75
|
+
SafeAutoCorrect: false
|
65
76
|
VersionAdded: '0.49'
|
77
|
+
VersionChanged: '2.5'
|
66
78
|
|
67
79
|
Rails/ApplicationMailer:
|
68
80
|
Description: 'Check that mailers subclass ApplicationMailer.'
|
69
81
|
Enabled: true
|
82
|
+
SafeAutoCorrect: false
|
70
83
|
VersionAdded: '2.4'
|
84
|
+
VersionChanged: '2.5'
|
71
85
|
|
72
86
|
Rails/ApplicationRecord:
|
73
87
|
Description: 'Check that models subclass ApplicationRecord.'
|
74
88
|
Enabled: true
|
89
|
+
SafeAutoCorrect: false
|
75
90
|
VersionAdded: '0.49'
|
91
|
+
VersionChanged: '2.5'
|
76
92
|
|
77
93
|
Rails/AssertNot:
|
78
94
|
Description: 'Use `assert_not` instead of `assert !`.'
|
@@ -84,7 +100,7 @@ Rails/AssertNot:
|
|
84
100
|
Rails/BelongsTo:
|
85
101
|
Description: >-
|
86
102
|
Use `optional: true` instead of `required: false` for
|
87
|
-
`belongs_to` relations
|
103
|
+
`belongs_to` relations.
|
88
104
|
Enabled: true
|
89
105
|
VersionAdded: '0.62'
|
90
106
|
|
@@ -111,6 +127,14 @@ Rails/BulkChangeTable:
|
|
111
127
|
Include:
|
112
128
|
- db/migrate/*.rb
|
113
129
|
|
130
|
+
Rails/ContentTag:
|
131
|
+
Description: 'Use `tag` instead of `content_tag`.'
|
132
|
+
Reference:
|
133
|
+
- 'https://github.com/rails/rails/issues/25195'
|
134
|
+
- 'https://api.rubyonrails.org/classes/ActionView/Helpers/TagHelper.html#method-i-content_tag'
|
135
|
+
Enabled: true
|
136
|
+
VersionAdded: '2.6'
|
137
|
+
|
114
138
|
Rails/CreateTableWithTimestamps:
|
115
139
|
Description: >-
|
116
140
|
Checks the migration for which timestamps are not included
|
@@ -137,6 +161,12 @@ Rails/Date:
|
|
137
161
|
- strict
|
138
162
|
- flexible
|
139
163
|
|
164
|
+
Rails/DefaultScope:
|
165
|
+
Description: 'Avoid use of `default_scope`.'
|
166
|
+
StyleGuide: 'https://rails.rubystyle.guide#avoid-default-scope'
|
167
|
+
Enabled: false
|
168
|
+
VersionAdded: '2.7'
|
169
|
+
|
140
170
|
Rails/Delegate:
|
141
171
|
Description: 'Prefer delegate method for delegations.'
|
142
172
|
Enabled: true
|
@@ -157,8 +187,14 @@ Rails/DynamicFindBy:
|
|
157
187
|
StyleGuide: 'https://rails.rubystyle.guide#find_by'
|
158
188
|
Enabled: true
|
159
189
|
VersionAdded: '0.44'
|
190
|
+
VersionChanged: '2.6'
|
191
|
+
# The `Whitelist` has been deprecated, Please use `AllowedMethods` instead.
|
160
192
|
Whitelist:
|
161
193
|
- find_by_sql
|
194
|
+
AllowedMethods:
|
195
|
+
- find_by_sql
|
196
|
+
AllowedReceivers:
|
197
|
+
- Gem::Specification
|
162
198
|
|
163
199
|
Rails/EnumHash:
|
164
200
|
Description: 'Prefer hash syntax over array syntax when defining enums.'
|
@@ -176,7 +212,7 @@ Rails/EnumUniqueness:
|
|
176
212
|
- app/models/**/*.rb
|
177
213
|
|
178
214
|
Rails/EnvironmentComparison:
|
179
|
-
Description: "Favor `Rails.env.production?` over `Rails.env == 'production'
|
215
|
+
Description: "Favor `Rails.env.production?` over `Rails.env == 'production'`."
|
180
216
|
Enabled: true
|
181
217
|
VersionAdded: '0.52'
|
182
218
|
|
@@ -212,6 +248,14 @@ Rails/FindBy:
|
|
212
248
|
Include:
|
213
249
|
- app/models/**/*.rb
|
214
250
|
|
251
|
+
Rails/FindById:
|
252
|
+
Description: >-
|
253
|
+
Favor the use of `find` over `where.take!`, `find_by!`, and `find_by_id!` when you
|
254
|
+
need to retrieve a single record by primary key when you expect it to be found.
|
255
|
+
StyleGuide: 'https://rails.rubystyle.guide/#find'
|
256
|
+
Enabled: 'pending'
|
257
|
+
VersionAdded: '2.7'
|
258
|
+
|
215
259
|
Rails/FindEach:
|
216
260
|
Description: 'Prefer all.find_each over all.find.'
|
217
261
|
StyleGuide: 'https://rails.rubystyle.guide#find-each'
|
@@ -237,7 +281,7 @@ Rails/HasManyOrHasOneDependent:
|
|
237
281
|
- app/models/**/*.rb
|
238
282
|
|
239
283
|
Rails/HelperInstanceVariable:
|
240
|
-
Description: 'Do not use instance variables in helpers'
|
284
|
+
Description: 'Do not use instance variables in helpers.'
|
241
285
|
Enabled: true
|
242
286
|
VersionAdded: '2.0'
|
243
287
|
Include:
|
@@ -268,6 +312,22 @@ Rails/IgnoredSkipActionFilterOption:
|
|
268
312
|
Include:
|
269
313
|
- app/controllers/**/*.rb
|
270
314
|
|
315
|
+
Rails/IndexBy:
|
316
|
+
Description: 'Prefer `index_by` over `each_with_object` or `map`.'
|
317
|
+
Enabled: true
|
318
|
+
VersionAdded: '2.5'
|
319
|
+
|
320
|
+
Rails/IndexWith:
|
321
|
+
Description: 'Prefer `index_with` over `each_with_object` or `map`.'
|
322
|
+
Enabled: true
|
323
|
+
VersionAdded: '2.5'
|
324
|
+
|
325
|
+
Rails/Inquiry:
|
326
|
+
Description: "Prefer Ruby's comparison operators over Active Support's `Array#inquiry` and `String#inquiry`."
|
327
|
+
StyleGuide: 'https://rails.rubystyle.guide/#inquiry'
|
328
|
+
Enabled: 'pending'
|
329
|
+
VersionAdded: '2.7'
|
330
|
+
|
271
331
|
Rails/InverseOf:
|
272
332
|
Description: 'Checks for associations where the inverse cannot be determined automatically.'
|
273
333
|
Enabled: true
|
@@ -293,8 +353,33 @@ Rails/LinkToBlank:
|
|
293
353
|
Enabled: true
|
294
354
|
VersionAdded: '0.62'
|
295
355
|
|
356
|
+
Rails/MailerName:
|
357
|
+
Description: 'Mailer should end with `Mailer` suffix.'
|
358
|
+
StyleGuide: 'https://rails.rubystyle.guide/#mailer-name'
|
359
|
+
Enabled: 'pending'
|
360
|
+
VersionAdded: '2.7'
|
361
|
+
Include:
|
362
|
+
- app/mailers/**/*.rb
|
363
|
+
|
364
|
+
Rails/MatchRoute:
|
365
|
+
Description: >-
|
366
|
+
Don't use `match` to define any routes unless there is a need to map multiple request types
|
367
|
+
among [:get, :post, :patch, :put, :delete] to a single action using the `:via` option.
|
368
|
+
StyleGuide: 'https://rails.rubystyle.guide/#no-match-routes'
|
369
|
+
Enabled: 'pending'
|
370
|
+
VersionAdded: '2.7'
|
371
|
+
Include:
|
372
|
+
- config/routes.rb
|
373
|
+
- config/routes/**/*.rb
|
374
|
+
|
375
|
+
Rails/NegateInclude:
|
376
|
+
Description: 'Prefer `collection.exclude?(obj)` over `!collection.include?(obj)`.'
|
377
|
+
StyleGuide: 'https://rails.rubystyle.guide#exclude'
|
378
|
+
Enabled: 'pending'
|
379
|
+
VersionAdded: '2.7'
|
380
|
+
|
296
381
|
Rails/NotNullColumn:
|
297
|
-
Description: 'Do not add a NOT NULL column without a default value'
|
382
|
+
Description: 'Do not add a NOT NULL column without a default value.'
|
298
383
|
Enabled: true
|
299
384
|
VersionAdded: '0.43'
|
300
385
|
Include:
|
@@ -316,6 +401,32 @@ Rails/OutputSafety:
|
|
316
401
|
Enabled: true
|
317
402
|
VersionAdded: '0.41'
|
318
403
|
|
404
|
+
Rails/Pick:
|
405
|
+
Description: 'Prefer `pick` over `pluck(...).first`.'
|
406
|
+
StyleGuide: 'https://rails.rubystyle.guide#pick'
|
407
|
+
Enabled: true
|
408
|
+
Safe: false
|
409
|
+
VersionAdded: '2.6'
|
410
|
+
|
411
|
+
Rails/Pluck:
|
412
|
+
Description: 'Prefer `pluck` over `map { ... }`.'
|
413
|
+
StyleGuide: 'https://rails.rubystyle.guide#pluck'
|
414
|
+
Enabled: 'pending'
|
415
|
+
VersionAdded: '2.7'
|
416
|
+
|
417
|
+
Rails/PluckId:
|
418
|
+
Description: 'Use `ids` instead of `pluck(:id)` or `pluck(primary_key)`.'
|
419
|
+
StyleGuide: 'https://rails.rubystyle.guide/#ids'
|
420
|
+
Enabled: 'pending'
|
421
|
+
Safe: false
|
422
|
+
VersionAdded: '2.7'
|
423
|
+
|
424
|
+
Rails/PluckInWhere:
|
425
|
+
Description: 'Use `select` instead of `pluck` in `where` query methods.'
|
426
|
+
Enabled: 'pending'
|
427
|
+
Safe: false
|
428
|
+
VersionAdded: '2.7'
|
429
|
+
|
319
430
|
Rails/PluralizationGrammar:
|
320
431
|
Description: 'Checks for incorrect grammar when using methods like `3.day.ago`.'
|
321
432
|
Enabled: true
|
@@ -343,9 +454,12 @@ Rails/RakeEnvironment:
|
|
343
454
|
Enabled: true
|
344
455
|
Safe: false
|
345
456
|
VersionAdded: '2.4'
|
457
|
+
VersionChanged: '2.6'
|
346
458
|
Include:
|
347
459
|
- '**/Rakefile'
|
348
460
|
- '**/*.rake'
|
461
|
+
Exclude:
|
462
|
+
- 'lib/capistrano/tasks/**/*.rake'
|
349
463
|
|
350
464
|
Rails/ReadWriteAttribute:
|
351
465
|
Description: >-
|
@@ -367,6 +481,11 @@ Rails/RedundantAllowNil:
|
|
367
481
|
Include:
|
368
482
|
- app/models/**/*.rb
|
369
483
|
|
484
|
+
Rails/RedundantForeignKey:
|
485
|
+
Description: 'Checks for associations where the `:foreign_key` option is redundant.'
|
486
|
+
Enabled: true
|
487
|
+
VersionAdded: '2.6'
|
488
|
+
|
370
489
|
Rails/RedundantReceiverInWithOptions:
|
371
490
|
Description: 'Checks for redundant receiver in `with_options`.'
|
372
491
|
Enabled: true
|
@@ -381,6 +500,10 @@ Rails/RefuteMethods:
|
|
381
500
|
Description: 'Use `assert_not` methods instead of `refute` methods.'
|
382
501
|
Enabled: true
|
383
502
|
VersionAdded: '0.56'
|
503
|
+
EnforcedStyle: assert_not
|
504
|
+
SupportedStyles:
|
505
|
+
- assert_not
|
506
|
+
- refute
|
384
507
|
Include:
|
385
508
|
- '**/test/**/*'
|
386
509
|
|
@@ -391,6 +514,20 @@ Rails/RelativeDateConstant:
|
|
391
514
|
VersionChanged: '0.59'
|
392
515
|
AutoCorrect: false
|
393
516
|
|
517
|
+
Rails/RenderInline:
|
518
|
+
Description: 'Prefer using a template over inline rendering.'
|
519
|
+
StyleGuide: 'https://rails.rubystyle.guide/#inline-rendering'
|
520
|
+
Enabled: 'pending'
|
521
|
+
VersionAdded: '2.7'
|
522
|
+
|
523
|
+
Rails/RenderPlainText:
|
524
|
+
Description: 'Prefer `render plain:` over `render text:`.'
|
525
|
+
StyleGuide: 'https://rails.rubystyle.guide/#plain-text-rendering'
|
526
|
+
Enabled: 'pending'
|
527
|
+
VersionAdded: '2.7'
|
528
|
+
# Convert only when `content_type` is explicitly set to `text/plain`.
|
529
|
+
ContentTypeCompatibility: true
|
530
|
+
|
394
531
|
Rails/RequestReferer:
|
395
532
|
Description: 'Use consistent syntax for request.referer.'
|
396
533
|
Enabled: true
|
@@ -410,7 +547,7 @@ Rails/ReversibleMigration:
|
|
410
547
|
- db/migrate/*.rb
|
411
548
|
|
412
549
|
Rails/SafeNavigation:
|
413
|
-
Description: "Use Ruby's safe navigation operator (`&.`) instead of `try
|
550
|
+
Description: "Use Ruby's safe navigation operator (`&.`) instead of `try!`."
|
414
551
|
Enabled: true
|
415
552
|
VersionAdded: '0.43'
|
416
553
|
# This will convert usages of `try` to use safe navigation as well as `try!`.
|
@@ -448,6 +585,16 @@ Rails/ScopeArgs:
|
|
448
585
|
Include:
|
449
586
|
- app/models/**/*.rb
|
450
587
|
|
588
|
+
Rails/ShortI18n:
|
589
|
+
Description: 'Use the short form of the I18n methods: `t` instead of `translate` and `l` instead of `localize`.'
|
590
|
+
StyleGuide: 'https://rails.rubystyle.guide/#short-i18n'
|
591
|
+
Enabled: 'pending'
|
592
|
+
VersionAdded: '2.7'
|
593
|
+
EnforcedStyle: conservative
|
594
|
+
SupportedStyles:
|
595
|
+
- conservative
|
596
|
+
- aggressive
|
597
|
+
|
451
598
|
Rails/SkipsModelValidations:
|
452
599
|
Description: >-
|
453
600
|
Use methods that skips model validations with caution.
|
@@ -455,20 +602,27 @@ Rails/SkipsModelValidations:
|
|
455
602
|
Reference: 'https://guides.rubyonrails.org/active_record_validations.html#skipping-validations'
|
456
603
|
Enabled: true
|
457
604
|
VersionAdded: '0.47'
|
458
|
-
VersionChanged: '
|
459
|
-
|
605
|
+
VersionChanged: '2.7'
|
606
|
+
ForbiddenMethods:
|
460
607
|
- decrement!
|
461
608
|
- decrement_counter
|
462
609
|
- increment!
|
463
610
|
- increment_counter
|
611
|
+
- insert
|
612
|
+
- insert!
|
613
|
+
- insert_all
|
614
|
+
- insert_all!
|
464
615
|
- toggle!
|
465
616
|
- touch
|
617
|
+
- touch_all
|
466
618
|
- update_all
|
467
619
|
- update_attribute
|
468
620
|
- update_column
|
469
621
|
- update_columns
|
470
622
|
- update_counters
|
471
|
-
|
623
|
+
- upsert
|
624
|
+
- upsert_all
|
625
|
+
AllowedMethods: []
|
472
626
|
|
473
627
|
Rails/TimeZone:
|
474
628
|
Description: 'Checks the correct usage of time zone aware methods.'
|
@@ -489,13 +643,20 @@ Rails/UniqBeforePluck:
|
|
489
643
|
Description: 'Prefer the use of uniq or distinct before pluck.'
|
490
644
|
Enabled: true
|
491
645
|
VersionAdded: '0.40'
|
492
|
-
VersionChanged: '
|
646
|
+
VersionChanged: '2.6'
|
493
647
|
EnforcedStyle: conservative
|
494
648
|
SupportedStyles:
|
495
649
|
- conservative
|
496
650
|
- aggressive
|
497
651
|
AutoCorrect: false
|
498
652
|
|
653
|
+
Rails/UniqueValidationWithoutIndex:
|
654
|
+
Description: 'Uniqueness validation should be with a unique index.'
|
655
|
+
Enabled: true
|
656
|
+
VersionAdded: '2.5'
|
657
|
+
Include:
|
658
|
+
- app/models/**/*.rb
|
659
|
+
|
499
660
|
Rails/UnknownEnv:
|
500
661
|
Description: 'Use correct environment name.'
|
501
662
|
Enabled: true
|
@@ -512,3 +673,12 @@ Rails/Validation:
|
|
512
673
|
VersionChanged: '0.41'
|
513
674
|
Include:
|
514
675
|
- app/models/**/*.rb
|
676
|
+
|
677
|
+
Rails/WhereExists:
|
678
|
+
Description: 'Prefer `exists?(...)` over `where(...).exists?`.'
|
679
|
+
Enabled: 'pending'
|
680
|
+
VersionAdded: '2.7'
|
681
|
+
|
682
|
+
# Accept `redirect_to(...) and return` and similar cases.
|
683
|
+
Style/AndOr:
|
684
|
+
EnforcedStyle: conditionals
|
data/lib/rubocop-rails.rb
CHANGED
@@ -2,10 +2,13 @@
|
|
2
2
|
|
3
3
|
require 'rubocop'
|
4
4
|
require 'rack/utils'
|
5
|
+
require 'active_support/inflector'
|
5
6
|
|
6
7
|
require_relative 'rubocop/rails'
|
7
8
|
require_relative 'rubocop/rails/version'
|
8
9
|
require_relative 'rubocop/rails/inject'
|
10
|
+
require_relative 'rubocop/rails/schema_loader'
|
11
|
+
require_relative 'rubocop/rails/schema_loader/schema'
|
9
12
|
|
10
13
|
RuboCop::Rails::Inject.defaults!
|
11
14
|
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# A mixin to extend cops for Active Record features
|
6
|
+
module ActiveRecordHelper
|
7
|
+
extend NodePattern::Macros
|
8
|
+
|
9
|
+
WHERE_METHODS = %i[where rewhere].freeze
|
10
|
+
|
11
|
+
def_node_search :find_set_table_name, <<~PATTERN
|
12
|
+
(send self :table_name= {str sym})
|
13
|
+
PATTERN
|
14
|
+
|
15
|
+
def_node_search :find_belongs_to, <<~PATTERN
|
16
|
+
(send nil? :belongs_to {str sym} ...)
|
17
|
+
PATTERN
|
18
|
+
|
19
|
+
def external_dependency_checksum
|
20
|
+
return @external_dependency_checksum if defined?(@external_dependency_checksum)
|
21
|
+
|
22
|
+
schema_path = RuboCop::Rails::SchemaLoader.db_schema_path
|
23
|
+
return nil if schema_path.nil?
|
24
|
+
|
25
|
+
schema_code = File.read(schema_path)
|
26
|
+
|
27
|
+
@external_dependency_checksum ||= Digest::SHA1.hexdigest(schema_code)
|
28
|
+
end
|
29
|
+
|
30
|
+
def schema
|
31
|
+
RuboCop::Rails::SchemaLoader.load(target_ruby_version)
|
32
|
+
end
|
33
|
+
|
34
|
+
def table_name(class_node)
|
35
|
+
table_name = find_set_table_name(class_node).to_a.last&.first_argument
|
36
|
+
return table_name.value.to_s if table_name
|
37
|
+
|
38
|
+
namespaces = class_node.each_ancestor(:class, :module)
|
39
|
+
[class_node, *namespaces]
|
40
|
+
.reverse
|
41
|
+
.map { |klass| klass.identifier.children[1] }.join('_')
|
42
|
+
.tableize
|
43
|
+
end
|
44
|
+
|
45
|
+
# Resolve relation into column name.
|
46
|
+
# It just returns column_name if the column exists.
|
47
|
+
# Or it tries to resolve column_name as a relation.
|
48
|
+
# It returns `nil` if it can't resolve.
|
49
|
+
#
|
50
|
+
# @param name [String]
|
51
|
+
# @param class_node [RuboCop::AST::Node]
|
52
|
+
# @param table [RuboCop::Rails::SchemaLoader::Table]
|
53
|
+
# @return [String, nil]
|
54
|
+
def resolve_relation_into_column(name:, class_node:, table:)
|
55
|
+
return name if table.with_column?(name: name)
|
56
|
+
|
57
|
+
find_belongs_to(class_node) do |belongs_to|
|
58
|
+
next unless belongs_to.first_argument.value.to_s == name
|
59
|
+
|
60
|
+
fk = foreign_key_of(belongs_to) || "#{name}_id"
|
61
|
+
return fk if table.with_column?(name: fk)
|
62
|
+
end
|
63
|
+
nil
|
64
|
+
end
|
65
|
+
|
66
|
+
def foreign_key_of(belongs_to)
|
67
|
+
options = belongs_to.last_argument
|
68
|
+
return unless options.hash_type?
|
69
|
+
|
70
|
+
options.each_pair.find do |pair|
|
71
|
+
next unless pair.key.sym_type? && pair.key.value == :foreign_key
|
72
|
+
next unless pair.value.sym_type? || pair.value.str_type?
|
73
|
+
|
74
|
+
break pair.value.value.to_s
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def in_where?(node)
|
79
|
+
send_node = node.each_ancestor(:send).first
|
80
|
+
send_node && WHERE_METHODS.include?(send_node.method_name)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|