rubocop-rails 2.5.2 → 2.8.1

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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +2 -2
  4. data/config/default.yml +192 -11
  5. data/lib/rubocop/cop/mixin/active_record_helper.rb +9 -3
  6. data/lib/rubocop/cop/mixin/index_method.rb +25 -1
  7. data/lib/rubocop/cop/rails/active_record_callbacks_order.rb +143 -0
  8. data/lib/rubocop/cop/rails/after_commit_override.rb +91 -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 +41 -15
  14. data/lib/rubocop/cop/rails/exit.rb +2 -2
  15. data/lib/rubocop/cop/rails/file_path.rb +2 -1
  16. data/lib/rubocop/cop/rails/find_by_id.rb +103 -0
  17. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +1 -5
  18. data/lib/rubocop/cop/rails/helper_instance_variable.rb +2 -0
  19. data/lib/rubocop/cop/rails/http_positional_arguments.rb +7 -1
  20. data/lib/rubocop/cop/rails/http_status.rb +2 -0
  21. data/lib/rubocop/cop/rails/index_by.rb +9 -1
  22. data/lib/rubocop/cop/rails/index_with.rb +9 -1
  23. data/lib/rubocop/cop/rails/inquiry.rb +38 -0
  24. data/lib/rubocop/cop/rails/inverse_of.rb +0 -4
  25. data/lib/rubocop/cop/rails/link_to_blank.rb +3 -3
  26. data/lib/rubocop/cop/rails/mailer_name.rb +80 -0
  27. data/lib/rubocop/cop/rails/match_route.rb +119 -0
  28. data/lib/rubocop/cop/rails/negate_include.rb +39 -0
  29. data/lib/rubocop/cop/rails/order_by_id.rb +53 -0
  30. data/lib/rubocop/cop/rails/pick.rb +55 -0
  31. data/lib/rubocop/cop/rails/pluck.rb +59 -0
  32. data/lib/rubocop/cop/rails/pluck_id.rb +58 -0
  33. data/lib/rubocop/cop/rails/pluck_in_where.rb +70 -0
  34. data/lib/rubocop/cop/rails/presence.rb +2 -6
  35. data/lib/rubocop/cop/rails/rake_environment.rb +17 -0
  36. data/lib/rubocop/cop/rails/redundant_foreign_key.rb +80 -0
  37. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +0 -3
  38. data/lib/rubocop/cop/rails/reflection_class_name.rb +1 -1
  39. data/lib/rubocop/cop/rails/relative_date_constant.rb +5 -2
  40. data/lib/rubocop/cop/rails/render_inline.rb +40 -0
  41. data/lib/rubocop/cop/rails/render_plain_text.rb +76 -0
  42. data/lib/rubocop/cop/rails/reversible_migration.rb +80 -1
  43. data/lib/rubocop/cop/rails/safe_navigation.rb +1 -1
  44. data/lib/rubocop/cop/rails/save_bang.rb +8 -9
  45. data/lib/rubocop/cop/rails/short_i18n.rb +76 -0
  46. data/lib/rubocop/cop/rails/skips_model_validations.rb +46 -8
  47. data/lib/rubocop/cop/rails/squished_sql_heredocs.rb +83 -0
  48. data/lib/rubocop/cop/rails/time_zone.rb +1 -3
  49. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +14 -12
  50. data/lib/rubocop/cop/rails/unique_validation_without_index.rb +16 -6
  51. data/lib/rubocop/cop/rails/unknown_env.rb +18 -6
  52. data/lib/rubocop/cop/rails/where_exists.rb +131 -0
  53. data/lib/rubocop/cop/rails/where_not.rb +108 -0
  54. data/lib/rubocop/cop/rails_cops.rb +21 -0
  55. data/lib/rubocop/rails/schema_loader/schema.rb +4 -4
  56. data/lib/rubocop/rails/version.rb +1 -1
  57. metadata +31 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dec32a9f0b296ef0a59bb3e93086ce5092ef18f49f546643588244503b94c7bc
4
- data.tar.gz: c1f270a92e19d8403896420bb6dfb5b58a389e8042f16513c3efd8aaf6ab0abb
3
+ metadata.gz: 49338e1944d78e63ec06fc37e16cbe3010f68f94d99ad24d5353be0c156bf8cb
4
+ data.tar.gz: 90823cd3bac084df9ac449fb6b0cb07a570721d2449c755432f022fb7c558e54
5
5
  SHA512:
6
- metadata.gz: 74cfd98f2b2506d2079e034f3e973d07eb3295b247b5dd48ccaebb5bc3461e4ad1c1bc6a2935b3b978203ecbe5cd1db43d616095c0b9a673dfc2222ff2aa79cf
7
- data.tar.gz: 3b48ca258cf1c4910417b2cadcf24244da5ac2d837a730cb584c0096e66b3688e6115ed93d22b619fb6224f84fc23eff250852498c4e6cab5c7f02ac3943fe71
6
+ metadata.gz: c242d3a6cdea9df1e4e7d9000e55db30d68dfd21317a286ad097c34a52e6cbd53a8fc6442a3333a312373adf8d7bfd05b562cf9a7391a752a7dccdc357a1b87e
7
+ data.tar.gz: fafe45955b9f0b50e403f37bdb499cdb78c6883f9472faba784e4e6e64a0fa661902d1700d38bd3a1d8c8a1c1cfc7ff2751e01cd37174cdda9025e9ef4195c43
@@ -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
@@ -78,13 +78,13 @@ Rails/FindBy:
78
78
 
79
79
  ## Documentation
80
80
 
81
- You can read a lot more about RuboCop Rails in its [official docs](https://docs.rubocop.org/projects/rails/).
81
+ You can read a lot more about RuboCop Rails in its [official docs](https://docs.rubocop.org/rubocop-rails/).
82
82
 
83
83
  ## Compatibility
84
84
 
85
85
  Rails cops support the following versions:
86
86
 
87
- - Rails 4.0+
87
+ - Rails 4.2+
88
88
 
89
89
  ## Contributing
90
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
@@ -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
@@ -92,7 +108,7 @@ Rails/AssertNot:
92
108
  Rails/BelongsTo:
93
109
  Description: >-
94
110
  Use `optional: true` instead of `required: false` for
95
- `belongs_to` relations'
111
+ `belongs_to` relations.
96
112
  Enabled: true
97
113
  VersionAdded: '0.62'
98
114
 
@@ -119,6 +135,14 @@ Rails/BulkChangeTable:
119
135
  Include:
120
136
  - db/migrate/*.rb
121
137
 
138
+ Rails/ContentTag:
139
+ Description: 'Use `tag` instead of `content_tag`.'
140
+ Reference:
141
+ - 'https://github.com/rails/rails/issues/25195'
142
+ - 'https://api.rubyonrails.org/classes/ActionView/Helpers/TagHelper.html#method-i-content_tag'
143
+ Enabled: true
144
+ VersionAdded: '2.6'
145
+
122
146
  Rails/CreateTableWithTimestamps:
123
147
  Description: >-
124
148
  Checks the migration for which timestamps are not included
@@ -145,6 +169,12 @@ Rails/Date:
145
169
  - strict
146
170
  - flexible
147
171
 
172
+ Rails/DefaultScope:
173
+ Description: 'Avoid use of `default_scope`.'
174
+ StyleGuide: 'https://rails.rubystyle.guide#avoid-default-scope'
175
+ Enabled: false
176
+ VersionAdded: '2.7'
177
+
148
178
  Rails/Delegate:
149
179
  Description: 'Prefer delegate method for delegations.'
150
180
  Enabled: true
@@ -165,8 +195,14 @@ Rails/DynamicFindBy:
165
195
  StyleGuide: 'https://rails.rubystyle.guide#find_by'
166
196
  Enabled: true
167
197
  VersionAdded: '0.44'
198
+ VersionChanged: '2.6'
199
+ # The `Whitelist` has been deprecated, Please use `AllowedMethods` instead.
168
200
  Whitelist:
169
201
  - find_by_sql
202
+ AllowedMethods:
203
+ - find_by_sql
204
+ AllowedReceivers:
205
+ - Gem::Specification
170
206
 
171
207
  Rails/EnumHash:
172
208
  Description: 'Prefer hash syntax over array syntax when defining enums.'
@@ -184,7 +220,7 @@ Rails/EnumUniqueness:
184
220
  - app/models/**/*.rb
185
221
 
186
222
  Rails/EnvironmentComparison:
187
- Description: "Favor `Rails.env.production?` over `Rails.env == 'production'`"
223
+ Description: "Favor `Rails.env.production?` over `Rails.env == 'production'`."
188
224
  Enabled: true
189
225
  VersionAdded: '0.52'
190
226
 
@@ -220,6 +256,14 @@ Rails/FindBy:
220
256
  Include:
221
257
  - app/models/**/*.rb
222
258
 
259
+ Rails/FindById:
260
+ Description: >-
261
+ Favor the use of `find` over `where.take!`, `find_by!`, and `find_by_id!` when you
262
+ need to retrieve a single record by primary key when you expect it to be found.
263
+ StyleGuide: 'https://rails.rubystyle.guide/#find'
264
+ Enabled: 'pending'
265
+ VersionAdded: '2.7'
266
+
223
267
  Rails/FindEach:
224
268
  Description: 'Prefer all.find_each over all.find.'
225
269
  StyleGuide: 'https://rails.rubystyle.guide#find-each'
@@ -245,7 +289,7 @@ Rails/HasManyOrHasOneDependent:
245
289
  - app/models/**/*.rb
246
290
 
247
291
  Rails/HelperInstanceVariable:
248
- Description: 'Do not use instance variables in helpers'
292
+ Description: 'Do not use instance variables in helpers.'
249
293
  Enabled: true
250
294
  VersionAdded: '2.0'
251
295
  Include:
@@ -277,14 +321,22 @@ Rails/IgnoredSkipActionFilterOption:
277
321
  - app/controllers/**/*.rb
278
322
 
279
323
  Rails/IndexBy:
280
- Description: 'Prefer `index_by` over `each_with_object` or `map`.'
324
+ Description: 'Prefer `index_by` over `each_with_object`, `to_h`, or `map`.'
281
325
  Enabled: true
282
326
  VersionAdded: '2.5'
327
+ VersionChanged: '2.8'
283
328
 
284
329
  Rails/IndexWith:
285
- Description: 'Prefer `index_with` over `each_with_object` or `map`.'
330
+ Description: 'Prefer `index_with` over `each_with_object`, `to_h`, or `map`.'
286
331
  Enabled: true
287
332
  VersionAdded: '2.5'
333
+ VersionChanged: '2.8'
334
+
335
+ Rails/Inquiry:
336
+ Description: "Prefer Ruby's comparison operators over Active Support's `Array#inquiry` and `String#inquiry`."
337
+ StyleGuide: 'https://rails.rubystyle.guide/#inquiry'
338
+ Enabled: 'pending'
339
+ VersionAdded: '2.7'
288
340
 
289
341
  Rails/InverseOf:
290
342
  Description: 'Checks for associations where the inverse cannot be determined automatically.'
@@ -311,13 +363,47 @@ Rails/LinkToBlank:
311
363
  Enabled: true
312
364
  VersionAdded: '0.62'
313
365
 
366
+ Rails/MailerName:
367
+ Description: 'Mailer should end with `Mailer` suffix.'
368
+ StyleGuide: 'https://rails.rubystyle.guide/#mailer-name'
369
+ Enabled: 'pending'
370
+ SafeAutoCorrect: false
371
+ VersionAdded: '2.7'
372
+ Include:
373
+ - app/mailers/**/*.rb
374
+
375
+ Rails/MatchRoute:
376
+ Description: >-
377
+ Don't use `match` to define any routes unless there is a need to map multiple request types
378
+ among [:get, :post, :patch, :put, :delete] to a single action using the `:via` option.
379
+ StyleGuide: 'https://rails.rubystyle.guide/#no-match-routes'
380
+ Enabled: 'pending'
381
+ VersionAdded: '2.7'
382
+ Include:
383
+ - config/routes.rb
384
+ - config/routes/**/*.rb
385
+
386
+ Rails/NegateInclude:
387
+ Description: 'Prefer `collection.exclude?(obj)` over `!collection.include?(obj)`.'
388
+ StyleGuide: 'https://rails.rubystyle.guide#exclude'
389
+ Enabled: 'pending'
390
+ VersionAdded: '2.7'
391
+
314
392
  Rails/NotNullColumn:
315
- Description: 'Do not add a NOT NULL column without a default value'
393
+ Description: 'Do not add a NOT NULL column without a default value.'
316
394
  Enabled: true
317
395
  VersionAdded: '0.43'
318
396
  Include:
319
397
  - db/migrate/*.rb
320
398
 
399
+ Rails/OrderById:
400
+ Description: >-
401
+ Do not use the `id` column for ordering.
402
+ Use a timestamp column to order chronologically.
403
+ StyleGuide: 'https://rails.rubystyle.guide/#order-by-id'
404
+ Enabled: false
405
+ VersionAdded: '2.8'
406
+
321
407
  Rails/Output:
322
408
  Description: 'Checks for calls to puts, print, etc.'
323
409
  Enabled: true
@@ -334,6 +420,37 @@ Rails/OutputSafety:
334
420
  Enabled: true
335
421
  VersionAdded: '0.41'
336
422
 
423
+ Rails/Pick:
424
+ Description: 'Prefer `pick` over `pluck(...).first`.'
425
+ StyleGuide: 'https://rails.rubystyle.guide#pick'
426
+ Enabled: true
427
+ Safe: false
428
+ VersionAdded: '2.6'
429
+
430
+ Rails/Pluck:
431
+ Description: 'Prefer `pluck` over `map { ... }`.'
432
+ StyleGuide: 'https://rails.rubystyle.guide#pluck'
433
+ Enabled: 'pending'
434
+ VersionAdded: '2.7'
435
+
436
+ Rails/PluckId:
437
+ Description: 'Use `ids` instead of `pluck(:id)` or `pluck(primary_key)`.'
438
+ StyleGuide: 'https://rails.rubystyle.guide/#ids'
439
+ Enabled: false
440
+ Safe: false
441
+ VersionAdded: '2.7'
442
+
443
+ Rails/PluckInWhere:
444
+ Description: 'Use `select` instead of `pluck` in `where` query methods.'
445
+ Enabled: 'pending'
446
+ Safe: false
447
+ VersionAdded: '2.7'
448
+ VersionChanged: '2.8'
449
+ EnforcedStyle: conservative
450
+ SupportedStyles:
451
+ - conservative
452
+ - aggressive
453
+
337
454
  Rails/PluralizationGrammar:
338
455
  Description: 'Checks for incorrect grammar when using methods like `3.day.ago`.'
339
456
  Enabled: true
@@ -361,6 +478,7 @@ Rails/RakeEnvironment:
361
478
  Enabled: true
362
479
  Safe: false
363
480
  VersionAdded: '2.4'
481
+ VersionChanged: '2.6'
364
482
  Include:
365
483
  - '**/Rakefile'
366
484
  - '**/*.rake'
@@ -387,6 +505,11 @@ Rails/RedundantAllowNil:
387
505
  Include:
388
506
  - app/models/**/*.rb
389
507
 
508
+ Rails/RedundantForeignKey:
509
+ Description: 'Checks for associations where the `:foreign_key` option is redundant.'
510
+ Enabled: true
511
+ VersionAdded: '2.6'
512
+
390
513
  Rails/RedundantReceiverInWithOptions:
391
514
  Description: 'Checks for redundant receiver in `with_options`.'
392
515
  Enabled: true
@@ -415,6 +538,20 @@ Rails/RelativeDateConstant:
415
538
  VersionChanged: '0.59'
416
539
  AutoCorrect: false
417
540
 
541
+ Rails/RenderInline:
542
+ Description: 'Prefer using a template over inline rendering.'
543
+ StyleGuide: 'https://rails.rubystyle.guide/#inline-rendering'
544
+ Enabled: 'pending'
545
+ VersionAdded: '2.7'
546
+
547
+ Rails/RenderPlainText:
548
+ Description: 'Prefer `render plain:` over `render text:`.'
549
+ StyleGuide: 'https://rails.rubystyle.guide/#plain-text-rendering'
550
+ Enabled: 'pending'
551
+ VersionAdded: '2.7'
552
+ # Convert only when `content_type` is explicitly set to `text/plain`.
553
+ ContentTypeCompatibility: true
554
+
418
555
  Rails/RequestReferer:
419
556
  Description: 'Use consistent syntax for request.referer.'
420
557
  Enabled: true
@@ -434,7 +571,7 @@ Rails/ReversibleMigration:
434
571
  - db/migrate/*.rb
435
572
 
436
573
  Rails/SafeNavigation:
437
- Description: "Use Ruby's safe navigation operator (`&.`) instead of `try!`"
574
+ Description: "Use Ruby's safe navigation operator (`&.`) instead of `try!`."
438
575
  Enabled: true
439
576
  VersionAdded: '0.43'
440
577
  # This will convert usages of `try` to use safe navigation as well as `try!`.
@@ -472,6 +609,16 @@ Rails/ScopeArgs:
472
609
  Include:
473
610
  - app/models/**/*.rb
474
611
 
612
+ Rails/ShortI18n:
613
+ Description: 'Use the short form of the I18n methods: `t` instead of `translate` and `l` instead of `localize`.'
614
+ StyleGuide: 'https://rails.rubystyle.guide/#short-i18n'
615
+ Enabled: 'pending'
616
+ VersionAdded: '2.7'
617
+ EnforcedStyle: conservative
618
+ SupportedStyles:
619
+ - conservative
620
+ - aggressive
621
+
475
622
  Rails/SkipsModelValidations:
476
623
  Description: >-
477
624
  Use methods that skips model validations with caution.
@@ -479,20 +626,33 @@ Rails/SkipsModelValidations:
479
626
  Reference: 'https://guides.rubyonrails.org/active_record_validations.html#skipping-validations'
480
627
  Enabled: true
481
628
  VersionAdded: '0.47'
482
- VersionChanged: '0.60'
483
- Blacklist:
629
+ VersionChanged: '2.7'
630
+ ForbiddenMethods:
484
631
  - decrement!
485
632
  - decrement_counter
486
633
  - increment!
487
634
  - increment_counter
635
+ - insert
636
+ - insert!
637
+ - insert_all
638
+ - insert_all!
488
639
  - toggle!
489
640
  - touch
641
+ - touch_all
490
642
  - update_all
491
643
  - update_attribute
492
644
  - update_column
493
645
  - update_columns
494
646
  - update_counters
495
- Whitelist: []
647
+ - upsert
648
+ - upsert_all
649
+ AllowedMethods: []
650
+
651
+ Rails/SquishedSQLHeredocs:
652
+ Description: 'Checks SQL heredocs to use `.squish`.'
653
+ StyleGuide: 'https://rails.rubystyle.guide/#squished-heredocs'
654
+ Enabled: 'pending'
655
+ VersionAdded: '2.8'
496
656
 
497
657
  Rails/TimeZone:
498
658
  Description: 'Checks the correct usage of time zone aware methods.'
@@ -513,11 +673,12 @@ Rails/UniqBeforePluck:
513
673
  Description: 'Prefer the use of uniq or distinct before pluck.'
514
674
  Enabled: true
515
675
  VersionAdded: '0.40'
516
- VersionChanged: '0.47'
676
+ VersionChanged: '2.8'
517
677
  EnforcedStyle: conservative
518
678
  SupportedStyles:
519
679
  - conservative
520
680
  - aggressive
681
+ SafeAutoCorrect: false
521
682
  AutoCorrect: false
522
683
 
523
684
  Rails/UniqueValidationWithoutIndex:
@@ -543,3 +704,23 @@ Rails/Validation:
543
704
  VersionChanged: '0.41'
544
705
  Include:
545
706
  - app/models/**/*.rb
707
+
708
+ Rails/WhereExists:
709
+ Description: 'Prefer `exists?(...)` over `where(...).exists?`.'
710
+ Enabled: 'pending'
711
+ EnforcedStyle: exists
712
+ SupportedStyles:
713
+ - exists
714
+ - where
715
+ VersionAdded: '2.7'
716
+ VersionChanged: '2.8'
717
+
718
+ Rails/WhereNot:
719
+ Description: 'Use `where.not(...)` instead of manually constructing negated SQL in `where`.'
720
+ StyleGuide: 'https://rails.rubystyle.guide/#where-not'
721
+ Enabled: 'pending'
722
+ VersionAdded: '2.8'
723
+
724
+ # Accept `redirect_to(...) and return` and similar cases.
725
+ Style/AndOr:
726
+ 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
@@ -15,9 +17,7 @@ module RuboCop
15
17
  PATTERN
16
18
 
17
19
  def external_dependency_checksum
18
- if defined?(@external_dependency_checksum)
19
- return @external_dependency_checksum
20
- end
20
+ return @external_dependency_checksum if defined?(@external_dependency_checksum)
21
21
 
22
22
  schema_path = RuboCop::Rails::SchemaLoader.db_schema_path
23
23
  return nil if schema_path.nil?
@@ -52,6 +52,7 @@ module RuboCop
52
52
  # @param table [RuboCop::Rails::SchemaLoader::Table]
53
53
  # @return [String, nil]
54
54
  def resolve_relation_into_column(name:, class_node:, table:)
55
+ return unless table
55
56
  return name if table.with_column?(name: name)
56
57
 
57
58
  find_belongs_to(class_node) do |belongs_to|
@@ -74,6 +75,11 @@ module RuboCop
74
75
  break pair.value.value.to_s
75
76
  end
76
77
  end
78
+
79
+ def in_where?(node)
80
+ send_node = node.each_ancestor(:send).first
81
+ send_node && WHERE_METHODS.include?(send_node.method_name)
82
+ end
77
83
  end
78
84
  end
79
85
  end
@@ -8,6 +8,12 @@ module RuboCop
8
8
  on_bad_each_with_object(node) do |*match|
9
9
  handle_possible_offense(node, match, 'each_with_object')
10
10
  end
11
+
12
+ return if target_ruby_version < 2.6
13
+
14
+ on_bad_to_h(node) do |*match|
15
+ handle_possible_offense(node, match, 'to_h { ... }')
16
+ end
11
17
  end
12
18
 
13
19
  def on_send(node)
@@ -40,6 +46,11 @@ module RuboCop
40
46
  raise NotImplementedError
41
47
  end
42
48
 
49
+ # @abstract Implemented with `def_node_matcher`
50
+ def on_bad_to_h(_node)
51
+ raise NotImplementedError
52
+ end
53
+
43
54
  # @abstract Implemented with `def_node_matcher`
44
55
  def on_bad_map_to_h(_node)
45
56
  raise NotImplementedError
@@ -73,6 +84,8 @@ module RuboCop
73
84
  def prepare_correction(node)
74
85
  if (match = on_bad_each_with_object(node))
75
86
  Autocorrection.from_each_with_object(node, match)
87
+ elsif (match = on_bad_to_h(node))
88
+ Autocorrection.from_to_h(node, match)
76
89
  elsif (match = on_bad_map_to_h(node))
77
90
  Autocorrection.from_map_to_h(node, match)
78
91
  elsif (match = on_bad_hash_brackets_map(node))
@@ -111,8 +124,19 @@ module RuboCop
111
124
  new(match, node, 0, 0)
112
125
  end
113
126
 
127
+ def self.from_to_h(node, match)
128
+ new(match, node, 0, 0)
129
+ end
130
+
114
131
  def self.from_map_to_h(node, match)
115
- strip_trailing_chars = node.parent&.block_type? ? 0 : '.to_h'.length
132
+ strip_trailing_chars = 0
133
+
134
+ unless node.parent&.block_type?
135
+ map_range = node.children.first.source_range
136
+ node_range = node.source_range
137
+ strip_trailing_chars = node_range.end_pos - map_range.end_pos
138
+ end
139
+
116
140
  new(match, node.children.first, 0, strip_trailing_chars)
117
141
  end
118
142