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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +5 -1
  4. data/config/default.yml +179 -9
  5. data/lib/rubocop-rails.rb +3 -0
  6. data/lib/rubocop/cop/mixin/active_record_helper.rb +84 -0
  7. data/lib/rubocop/cop/mixin/index_method.rb +161 -0
  8. data/lib/rubocop/cop/rails/active_record_callbacks_order.rb +145 -0
  9. data/lib/rubocop/cop/rails/content_tag.rb +69 -0
  10. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +1 -3
  11. data/lib/rubocop/cop/rails/default_scope.rb +54 -0
  12. data/lib/rubocop/cop/rails/delegate.rb +2 -4
  13. data/lib/rubocop/cop/rails/dynamic_find_by.rb +40 -15
  14. data/lib/rubocop/cop/rails/environment_comparison.rb +60 -14
  15. data/lib/rubocop/cop/rails/exit.rb +2 -2
  16. data/lib/rubocop/cop/rails/file_path.rb +2 -1
  17. data/lib/rubocop/cop/rails/find_by_id.rb +103 -0
  18. data/lib/rubocop/cop/rails/http_positional_arguments.rb +2 -2
  19. data/lib/rubocop/cop/rails/http_status.rb +2 -0
  20. data/lib/rubocop/cop/rails/index_by.rb +56 -0
  21. data/lib/rubocop/cop/rails/index_with.rb +59 -0
  22. data/lib/rubocop/cop/rails/inquiry.rb +34 -0
  23. data/lib/rubocop/cop/rails/inverse_of.rb +0 -4
  24. data/lib/rubocop/cop/rails/link_to_blank.rb +3 -3
  25. data/lib/rubocop/cop/rails/mailer_name.rb +80 -0
  26. data/lib/rubocop/cop/rails/match_route.rb +117 -0
  27. data/lib/rubocop/cop/rails/negate_include.rb +39 -0
  28. data/lib/rubocop/cop/rails/pick.rb +55 -0
  29. data/lib/rubocop/cop/rails/pluck.rb +59 -0
  30. data/lib/rubocop/cop/rails/pluck_id.rb +58 -0
  31. data/lib/rubocop/cop/rails/pluck_in_where.rb +36 -0
  32. data/lib/rubocop/cop/rails/presence.rb +2 -6
  33. data/lib/rubocop/cop/rails/rake_environment.rb +17 -0
  34. data/lib/rubocop/cop/rails/redundant_foreign_key.rb +80 -0
  35. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +0 -3
  36. data/lib/rubocop/cop/rails/refute_methods.rb +52 -26
  37. data/lib/rubocop/cop/rails/render_inline.rb +48 -0
  38. data/lib/rubocop/cop/rails/render_plain_text.rb +76 -0
  39. data/lib/rubocop/cop/rails/reversible_migration.rb +6 -1
  40. data/lib/rubocop/cop/rails/safe_navigation.rb +1 -1
  41. data/lib/rubocop/cop/rails/save_bang.rb +6 -7
  42. data/lib/rubocop/cop/rails/short_i18n.rb +76 -0
  43. data/lib/rubocop/cop/rails/skips_model_validations.rb +46 -8
  44. data/lib/rubocop/cop/rails/time_zone.rb +1 -3
  45. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +12 -12
  46. data/lib/rubocop/cop/rails/unique_validation_without_index.rb +155 -0
  47. data/lib/rubocop/cop/rails/unknown_env.rb +7 -6
  48. data/lib/rubocop/cop/rails/where_exists.rb +68 -0
  49. data/lib/rubocop/cop/rails_cops.rb +22 -0
  50. data/lib/rubocop/rails/schema_loader.rb +61 -0
  51. data/lib/rubocop/rails/schema_loader/schema.rb +190 -0
  52. data/lib/rubocop/rails/version.rb +1 -1
  53. metadata +46 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0cf251ed7e29a11391396009eb82eed3fa4684e100b26b9041d469da2db04133
4
- data.tar.gz: 440778968fbafa4dd3415741d8ef3c49e6025bee7ec85454a5b7012859e657c4
3
+ metadata.gz: 5a83fc9ded75b4055903b32234c6c9b878e76b22ee64b7e0d88cf2f54ac690d5
4
+ data.tar.gz: cb9cbde85b8117645e16c66d1670cffc61893eba8b5d5e3f530e7e42d81b147f
5
5
  SHA512:
6
- metadata.gz: fe54c2657de98b317f8df85618a4a00708be71dc8c7c924a43734773a1f3d31da6d85e44cbb983f5c10ecb235bf420ac86a4e67ac86a45b70e7c9b8403f4623e
7
- data.tar.gz: 4c9111285fe0211b5b1da14f8b31d2023a20e3b223dee3a1a3fcec0c66e622a0116ec783059a5161042640f92799b4df2b7585a4dd0ac96f12b06fa776886960
6
+ metadata.gz: 9df513d510b7a71d81bcf655088528ca642599702eca3f20d83eac18adcc15a3d2ab277760b78b9f86fc90df474409eaee454c6857623a2f459304fb74fdde00
7
+ data.tar.gz: 252a9b09c51b33b4ff53454fcc6ccaec41e719c283939475e643074305221a33652a9ab5649b9b2c51f36784bb67eeef5dbceee9b3852de936fed78073241dc0
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012-18 Bozhidar Batsov
1
+ Copyright (c) 2012-20 Bozhidar Batsov
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
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.0+
87
+ - Rails 4.2+
84
88
 
85
89
  ## Contributing
86
90
 
@@ -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: '0.60'
459
- Blacklist:
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
- Whitelist: []
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: '0.47'
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
@@ -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