rubocop-rails 2.8.1 → 2.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +16 -0
  3. data/config/default.yml +33 -1
  4. data/lib/rubocop/cop/mixin/active_record_helper.rb +4 -3
  5. data/lib/rubocop/cop/mixin/enforce_superclass.rb +40 -0
  6. data/lib/rubocop/cop/mixin/index_method.rb +8 -11
  7. data/lib/rubocop/cop/rails/action_filter.rb +10 -14
  8. data/lib/rubocop/cop/rails/active_record_aliases.rb +13 -17
  9. data/lib/rubocop/cop/rails/active_record_callbacks_order.rb +17 -12
  10. data/lib/rubocop/cop/rails/active_record_override.rb +1 -1
  11. data/lib/rubocop/cop/rails/active_support_aliases.rb +12 -21
  12. data/lib/rubocop/cop/rails/after_commit_override.rb +1 -1
  13. data/lib/rubocop/cop/rails/application_controller.rb +3 -7
  14. data/lib/rubocop/cop/rails/application_job.rb +2 -1
  15. data/lib/rubocop/cop/rails/application_mailer.rb +2 -7
  16. data/lib/rubocop/cop/rails/application_record.rb +2 -7
  17. data/lib/rubocop/cop/rails/arel_star.rb +41 -0
  18. data/lib/rubocop/cop/rails/assert_not.rb +8 -10
  19. data/lib/rubocop/cop/rails/attribute_default_block_value.rb +90 -0
  20. data/lib/rubocop/cop/rails/belongs_to.rb +9 -18
  21. data/lib/rubocop/cop/rails/blank.rb +27 -27
  22. data/lib/rubocop/cop/rails/bulk_change_table.rb +1 -1
  23. data/lib/rubocop/cop/rails/content_tag.rb +16 -16
  24. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +2 -1
  25. data/lib/rubocop/cop/rails/date.rb +10 -11
  26. data/lib/rubocop/cop/rails/default_scope.rb +11 -4
  27. data/lib/rubocop/cop/rails/delegate.rb +9 -9
  28. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +7 -8
  29. data/lib/rubocop/cop/rails/dynamic_find_by.rb +12 -11
  30. data/lib/rubocop/cop/rails/enum_hash.rb +11 -10
  31. data/lib/rubocop/cop/rails/enum_uniqueness.rb +2 -1
  32. data/lib/rubocop/cop/rails/environment_comparison.rb +18 -14
  33. data/lib/rubocop/cop/rails/exit.rb +4 -10
  34. data/lib/rubocop/cop/rails/file_path.rb +4 -3
  35. data/lib/rubocop/cop/rails/find_by.rb +13 -13
  36. data/lib/rubocop/cop/rails/find_by_id.rb +12 -21
  37. data/lib/rubocop/cop/rails/find_each.rb +16 -14
  38. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +3 -2
  39. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +3 -2
  40. data/lib/rubocop/cop/rails/helper_instance_variable.rb +2 -2
  41. data/lib/rubocop/cop/rails/http_positional_arguments.rb +19 -21
  42. data/lib/rubocop/cop/rails/http_status.rb +7 -9
  43. data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +8 -6
  44. data/lib/rubocop/cop/rails/index_by.rb +2 -1
  45. data/lib/rubocop/cop/rails/index_with.rb +2 -1
  46. data/lib/rubocop/cop/rails/inquiry.rb +4 -3
  47. data/lib/rubocop/cop/rails/inverse_of.rb +3 -2
  48. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +17 -15
  49. data/lib/rubocop/cop/rails/link_to_blank.rb +20 -22
  50. data/lib/rubocop/cop/rails/mailer_name.rb +19 -13
  51. data/lib/rubocop/cop/rails/match_route.rb +14 -13
  52. data/lib/rubocop/cop/rails/negate_include.rb +10 -8
  53. data/lib/rubocop/cop/rails/not_null_column.rb +2 -1
  54. data/lib/rubocop/cop/rails/order_by_id.rb +1 -2
  55. data/lib/rubocop/cop/rails/output.rb +5 -2
  56. data/lib/rubocop/cop/rails/output_safety.rb +3 -2
  57. data/lib/rubocop/cop/rails/pick.rb +14 -12
  58. data/lib/rubocop/cop/rails/pluck.rb +6 -9
  59. data/lib/rubocop/cop/rails/pluck_id.rb +4 -6
  60. data/lib/rubocop/cop/rails/pluck_in_where.rb +7 -7
  61. data/lib/rubocop/cop/rails/pluralization_grammar.rb +10 -14
  62. data/lib/rubocop/cop/rails/presence.rb +12 -13
  63. data/lib/rubocop/cop/rails/present.rb +30 -24
  64. data/lib/rubocop/cop/rails/rake_environment.rb +8 -10
  65. data/lib/rubocop/cop/rails/read_write_attribute.rb +12 -11
  66. data/lib/rubocop/cop/rails/redundant_allow_nil.rb +29 -31
  67. data/lib/rubocop/cop/rails/redundant_foreign_key.rb +9 -12
  68. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +11 -10
  69. data/lib/rubocop/cop/rails/reflection_class_name.rb +3 -2
  70. data/lib/rubocop/cop/rails/refute_methods.rb +9 -10
  71. data/lib/rubocop/cop/rails/relative_date_constant.rb +16 -8
  72. data/lib/rubocop/cop/rails/render_inline.rb +2 -1
  73. data/lib/rubocop/cop/rails/render_plain_text.rb +9 -14
  74. data/lib/rubocop/cop/rails/request_referer.rb +7 -7
  75. data/lib/rubocop/cop/rails/reversible_migration.rb +2 -6
  76. data/lib/rubocop/cop/rails/safe_navigation.rb +11 -10
  77. data/lib/rubocop/cop/rails/safe_navigation_with_blank.rb +5 -10
  78. data/lib/rubocop/cop/rails/save_bang.rb +17 -20
  79. data/lib/rubocop/cop/rails/scope_args.rb +2 -1
  80. data/lib/rubocop/cop/rails/short_i18n.rb +7 -9
  81. data/lib/rubocop/cop/rails/skips_model_validations.rb +4 -4
  82. data/lib/rubocop/cop/rails/squished_sql_heredocs.rb +5 -6
  83. data/lib/rubocop/cop/rails/time_zone.rb +22 -20
  84. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +4 -6
  85. data/lib/rubocop/cop/rails/unique_validation_without_index.rb +2 -2
  86. data/lib/rubocop/cop/rails/unknown_env.rb +2 -2
  87. data/lib/rubocop/cop/rails/validation.rb +15 -14
  88. data/lib/rubocop/cop/rails/where_equals.rb +94 -0
  89. data/lib/rubocop/cop/rails/where_exists.rb +8 -13
  90. data/lib/rubocop/cop/rails/where_not.rb +5 -16
  91. data/lib/rubocop/cop/rails_cops.rb +4 -0
  92. data/lib/rubocop/rails/schema_loader.rb +4 -4
  93. data/lib/rubocop/rails/schema_loader/schema.rb +1 -1
  94. data/lib/rubocop/rails/version.rb +5 -1
  95. metadata +19 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 49338e1944d78e63ec06fc37e16cbe3010f68f94d99ad24d5353be0c156bf8cb
4
- data.tar.gz: 90823cd3bac084df9ac449fb6b0cb07a570721d2449c755432f022fb7c558e54
3
+ metadata.gz: b997fb5d9995a5c7db5d151e13b86cf0dbd2b27f890e9ad116d11fab30a1b7e0
4
+ data.tar.gz: 91c6b0a496bcbe9c92b0833944b301e893c9f9ee6e75db0fb393436c9869dc81
5
5
  SHA512:
6
- metadata.gz: c242d3a6cdea9df1e4e7d9000e55db30d68dfd21317a286ad097c34a52e6cbd53a8fc6442a3333a312373adf8d7bfd05b562cf9a7391a752a7dccdc357a1b87e
7
- data.tar.gz: fafe45955b9f0b50e403f37bdb499cdb78c6883f9472faba784e4e6e64a0fa661902d1700d38bd3a1d8c8a1c1cfc7ff2751e01cd37174cdda9025e9ef4195c43
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).
@@ -98,6 +98,12 @@ Rails/ApplicationRecord:
98
98
  VersionAdded: '0.49'
99
99
  VersionChanged: '2.5'
100
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
+
101
107
  Rails/AssertNot:
102
108
  Description: 'Use `assert_not` instead of `assert !`.'
103
109
  Enabled: true
@@ -105,6 +111,13 @@ Rails/AssertNot:
105
111
  Include:
106
112
  - '**/test/**/*'
107
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
+
108
121
  Rails/BelongsTo:
109
122
  Description: >-
110
123
  Use `optional: true` instead of `required: false` for
@@ -269,8 +282,15 @@ Rails/FindEach:
269
282
  StyleGuide: 'https://rails.rubystyle.guide#find-each'
270
283
  Enabled: true
271
284
  VersionAdded: '0.30'
285
+ VersionChanged: '2.9'
272
286
  Include:
273
287
  - app/models/**/*.rb
288
+ IgnoredMethods:
289
+ # Methods that don't work well with `find_each`.
290
+ - order
291
+ - limit
292
+ - select
293
+ - lock
274
294
 
275
295
  Rails/HasAndBelongsToMany:
276
296
  Description: 'Prefer has_many :through to has_and_belongs_to_many.'
@@ -387,7 +407,9 @@ Rails/NegateInclude:
387
407
  Description: 'Prefer `collection.exclude?(obj)` over `!collection.include?(obj)`.'
388
408
  StyleGuide: 'https://rails.rubystyle.guide#exclude'
389
409
  Enabled: 'pending'
410
+ Safe: false
390
411
  VersionAdded: '2.7'
412
+ VersionChanged: '2.9'
391
413
 
392
414
  Rails/NotNullColumn:
393
415
  Description: 'Do not add a NOT NULL column without a default value.'
@@ -653,6 +675,10 @@ Rails/SquishedSQLHeredocs:
653
675
  StyleGuide: 'https://rails.rubystyle.guide/#squished-heredocs'
654
676
  Enabled: 'pending'
655
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
656
682
 
657
683
  Rails/TimeZone:
658
684
  Description: 'Checks the correct usage of time zone aware methods.'
@@ -705,6 +731,12 @@ Rails/Validation:
705
731
  Include:
706
732
  - app/models/**/*.rb
707
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
+
708
740
  Rails/WhereExists:
709
741
  Description: 'Prefer `exists?(...)` over `where(...).exists?`.'
710
742
  Enabled: 'pending'
@@ -717,7 +749,7 @@ Rails/WhereExists:
717
749
 
718
750
  Rails/WhereNot:
719
751
  Description: 'Use `where.not(...)` instead of manually constructing negated SQL in `where`.'
720
- StyleGuide: 'https://rails.rubystyle.guide/#where-not'
752
+ StyleGuide: 'https://rails.rubystyle.guide/#hash-conditions'
721
753
  Enabled: 'pending'
722
754
  VersionAdded: '2.8'
723
755
 
@@ -35,10 +35,11 @@ module RuboCop
35
35
  table_name = find_set_table_name(class_node).to_a.last&.first_argument
36
36
  return table_name.value.to_s if table_name
37
37
 
38
- namespaces = class_node.each_ancestor(:class, :module)
39
- [class_node, *namespaces]
38
+ class_nodes = class_node.defined_module.each_node
39
+ namespaces = class_node.each_ancestor(:class, :module).map(&:identifier)
40
+ [*class_nodes, *namespaces]
40
41
  .reverse
41
- .map { |klass| klass.identifier.children[1] }.join('_')
42
+ .map { |node| node.children[1] }.join('_')
42
43
  .tableize
43
44
  end
44
45
 
@@ -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,6 +4,8 @@ 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')
@@ -32,13 +34,6 @@ module RuboCop
32
34
  end
33
35
  end
34
36
 
35
- def autocorrect(node)
36
- lambda do |corrector|
37
- correction = prepare_correction(node)
38
- execute_correction(corrector, node, correction)
39
- end
40
- end
41
-
42
37
  private
43
38
 
44
39
  # @abstract Implemented with `def_node_matcher`
@@ -67,9 +62,11 @@ module RuboCop
67
62
  return if captures.noop_transformation?
68
63
 
69
64
  add_offense(
70
- node,
71
- message: "Prefer `#{new_method_name}` over `#{match_desc}`."
72
- )
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
73
70
  end
74
71
 
75
72
  def extract_captures(match)
@@ -119,7 +116,7 @@ module RuboCop
119
116
  end
120
117
 
121
118
  # Internal helper class to hold autocorrect data
122
- Autocorrection = Struct.new(:match, :block_node, :leading, :trailing) do # rubocop:disable Metrics/BlockLength
119
+ Autocorrection = Struct.new(:match, :block_node, :leading, :trailing) do
123
120
  def self.from_each_with_object(node, match)
124
121
  new(match, node, 0, 0)
125
122
  end
@@ -29,8 +29,9 @@ module RuboCop
29
29
  # after_filter :do_stuff
30
30
  # append_around_filter :do_stuff
31
31
  # skip_after_filter :do_stuff
32
- class ActionFilter < Cop
32
+ class ActionFilter < Base
33
33
  include ConfigurableEnforcedStyle
34
+ extend AutoCorrector
34
35
 
35
36
  MSG = 'Prefer `%<prefer>s` over `%<current>s`.'
36
37
 
@@ -66,6 +67,8 @@ module RuboCop
66
67
  skip_action_callback
67
68
  ].freeze
68
69
 
70
+ RESTRICT_ON_SEND = FILTER_METHODS + ACTION_METHODS
71
+
69
72
  def on_block(node)
70
73
  check_method_node(node.send_node)
71
74
  end
@@ -74,24 +77,17 @@ module RuboCop
74
77
  check_method_node(node) unless node.receiver
75
78
  end
76
79
 
77
- def autocorrect(node)
78
- lambda do |corrector|
79
- corrector.replace(node.loc.selector,
80
- preferred_method(node.loc.selector.source).to_s)
81
- end
82
- end
83
-
84
80
  private
85
81
 
86
82
  def check_method_node(node)
87
- return unless bad_methods.include?(node.method_name)
83
+ method_name = node.method_name
84
+ return unless bad_methods.include?(method_name)
88
85
 
89
- add_offense(node, location: :selector)
90
- end
86
+ message = format(MSG, prefer: preferred_method(method_name), current: method_name)
91
87
 
92
- def message(node)
93
- format(MSG, prefer: preferred_method(node.method_name),
94
- current: node.method_name)
88
+ add_offense(node.loc.selector, message: message) do |corrector|
89
+ corrector.replace(node.loc.selector, preferred_method(node.loc.selector.source))
90
+ end
95
91
  end
96
92
 
97
93
  def bad_methods
@@ -12,7 +12,9 @@ module RuboCop
12
12
  #
13
13
  # #good
14
14
  # Book.update!(author: 'Alice')
15
- class ActiveRecordAliases < Cop
15
+ class ActiveRecordAliases < Base
16
+ extend AutoCorrector
17
+
16
18
  MSG = 'Use `%<prefer>s` instead of `%<current>s`.'
17
19
 
18
20
  ALIASES = {
@@ -20,28 +22,22 @@ module RuboCop
20
22
  update_attributes!: :update!
21
23
  }.freeze
22
24
 
25
+ RESTRICT_ON_SEND = ALIASES.keys.freeze
26
+
23
27
  def on_send(node)
24
- ALIASES.each do |bad, good|
25
- next unless node.method?(bad)
28
+ method_name = node.method_name
29
+ alias_method = ALIASES[method_name]
26
30
 
27
- add_offense(node,
28
- message: format(MSG, prefer: good, current: bad),
29
- location: :selector,
30
- severity: :warning)
31
- break
31
+ add_offense(
32
+ node.loc.selector,
33
+ message: format(MSG, prefer: alias_method, current: method_name),
34
+ severity: :warning
35
+ ) do |corrector|
36
+ corrector.replace(node.loc.selector, alias_method)
32
37
  end
33
38
  end
34
39
 
35
40
  alias on_csend on_send
36
-
37
- def autocorrect(node)
38
- lambda do |corrector|
39
- corrector.replace(
40
- node.loc.selector,
41
- ALIASES[node.method_name].to_s
42
- )
43
- end
44
- end
45
41
  end
46
42
  end
47
43
  end
@@ -19,7 +19,9 @@ module RuboCop
19
19
  # after_commit :after_commit_callback
20
20
  # end
21
21
  #
22
- class ActiveRecordCallbacksOrder < Cop
22
+ class ActiveRecordCallbacksOrder < Base
23
+ extend AutoCorrector
24
+
23
25
  MSG = '`%<current>s` is supposed to appear before `%<previous>s`.'
24
26
 
25
27
  CALLBACKS_IN_ORDER = %i[
@@ -55,17 +57,20 @@ module RuboCop
55
57
  index = CALLBACKS_ORDER_MAP[callback]
56
58
 
57
59
  if index < previous_index
58
- message = format(MSG, current: callback,
59
- previous: previous_callback)
60
- add_offense(node, message: message)
60
+ message = format(MSG, current: callback, previous: previous_callback)
61
+ add_offense(node, message: message) do |corrector|
62
+ autocorrect(corrector, node)
63
+ end
61
64
  end
62
65
  previous_index = index
63
66
  previous_callback = callback
64
67
  end
65
68
  end
66
69
 
70
+ private
71
+
67
72
  # Autocorrect by swapping between two nodes autocorrecting them
68
- def autocorrect(node)
73
+ def autocorrect(corrector, node)
69
74
  previous = left_siblings_of(node).reverse_each.find do |sibling|
70
75
  callback?(sibling)
71
76
  end
@@ -73,14 +78,10 @@ module RuboCop
73
78
  current_range = source_range_with_comment(node)
74
79
  previous_range = source_range_with_comment(previous)
75
80
 
76
- lambda do |corrector|
77
- corrector.insert_before(previous_range, current_range.source)
78
- corrector.remove(current_range)
79
- end
81
+ corrector.insert_before(previous_range, current_range.source)
82
+ corrector.remove(current_range)
80
83
  end
81
84
 
82
- private
83
-
84
85
  def defined_callbacks(class_node)
85
86
  class_def = class_node.body
86
87
 
@@ -121,7 +122,7 @@ module RuboCop
121
122
 
122
123
  processed_source.comments_before_line(annotation_line)
123
124
  .reverse_each do |comment|
124
- if comment.location.line == annotation_line
125
+ if comment.location.line == annotation_line && !inline_comment?(comment)
125
126
  first_comment = comment
126
127
  annotation_line -= 1
127
128
  end
@@ -130,6 +131,10 @@ module RuboCop
130
131
  start_line_position(first_comment || node)
131
132
  end
132
133
 
134
+ def inline_comment?(comment)
135
+ !comment_line?(comment.loc.expression.source_line)
136
+ end
137
+
133
138
  def start_line_position(node)
134
139
  buffer.line_range(node.loc.line).begin_pos - 1
135
140
  end
@@ -24,7 +24,7 @@ module RuboCop
24
24
  # end
25
25
  # end
26
26
  #
27
- class ActiveRecordOverride < Cop
27
+ class ActiveRecordOverride < Base
28
28
  MSG =
29
29
  'Use %<prefer>s callbacks instead of overriding the Active Record ' \
30
30
  'method `%<bad>s`.'
@@ -19,8 +19,11 @@ module RuboCop
19
19
  # [1, 2, 'a'].append('b')
20
20
  # [1, 2, 'a'].prepend('b')
21
21
  #
22
- class ActiveSupportAliases < Cop
22
+ class ActiveSupportAliases < Base
23
+ extend AutoCorrector
24
+
23
25
  MSG = 'Use `%<prefer>s` instead of `%<current>s`.'
26
+ RESTRICT_ON_SEND = %i[starts_with? ends_with? append prepend].freeze
24
27
 
25
28
  ALIASES = {
26
29
  starts_with?: {
@@ -39,29 +42,17 @@ module RuboCop
39
42
 
40
43
  def on_send(node)
41
44
  ALIASES.each_key do |aliased_method|
42
- register_offense(node, aliased_method) if
43
- public_send(aliased_method, node)
44
- end
45
- end
45
+ next unless public_send(aliased_method, node)
46
46
 
47
- def autocorrect(node)
48
- return false if append(node)
47
+ preferred_method = ALIASES[aliased_method][:original]
48
+ message = format(MSG, prefer: preferred_method, current: aliased_method)
49
49
 
50
- lambda do |corrector|
51
- method_name = node.loc.selector.source
52
- replacement = ALIASES[method_name.to_sym][:original]
53
- corrector.replace(node.loc.selector, replacement.to_s)
54
- end
55
- end
56
-
57
- private
50
+ add_offense(node, message: message) do |corrector|
51
+ next if append(node)
58
52
 
59
- def register_offense(node, method_name)
60
- add_offense(
61
- node,
62
- message: format(MSG, prefer: ALIASES[method_name][:original],
63
- current: method_name)
64
- )
53
+ corrector.replace(node.loc.selector, preferred_method)
54
+ end
55
+ end
65
56
  end
66
57
  end
67
58
  end