rubocop-rails 2.15.2 → 2.20.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +23 -2
  4. data/config/default.yml +181 -13
  5. data/config/obsoletion.yml +10 -0
  6. data/lib/rubocop/cop/mixin/active_record_helper.rb +3 -6
  7. data/lib/rubocop/cop/mixin/active_record_migrations_helper.rb +1 -3
  8. data/lib/rubocop/cop/mixin/enforce_superclass.rb +1 -1
  9. data/lib/rubocop/cop/mixin/index_method.rb +7 -17
  10. data/lib/rubocop/cop/mixin/migrations_helper.rb +1 -1
  11. data/lib/rubocop/cop/rails/action_controller_flash_before_render.rb +112 -0
  12. data/lib/rubocop/cop/rails/action_controller_test_case.rb +2 -2
  13. data/lib/rubocop/cop/rails/action_filter.rb +1 -1
  14. data/lib/rubocop/cop/rails/action_order.rb +116 -0
  15. data/lib/rubocop/cop/rails/active_record_aliases.rb +3 -4
  16. data/lib/rubocop/cop/rails/active_record_callbacks_order.rb +6 -3
  17. data/lib/rubocop/cop/rails/active_record_override.rb +2 -5
  18. data/lib/rubocop/cop/rails/active_support_on_load.rb +70 -0
  19. data/lib/rubocop/cop/rails/add_column_index.rb +2 -5
  20. data/lib/rubocop/cop/rails/application_controller.rb +1 -1
  21. data/lib/rubocop/cop/rails/application_job.rb +2 -2
  22. data/lib/rubocop/cop/rails/application_mailer.rb +1 -1
  23. data/lib/rubocop/cop/rails/application_record.rb +1 -1
  24. data/lib/rubocop/cop/rails/arel_star.rb +1 -1
  25. data/lib/rubocop/cop/rails/assert_not.rb +1 -2
  26. data/lib/rubocop/cop/rails/belongs_to.rb +1 -4
  27. data/lib/rubocop/cop/rails/blank.rb +6 -7
  28. data/lib/rubocop/cop/rails/bulk_change_table.rb +7 -24
  29. data/lib/rubocop/cop/rails/compact_blank.rb +5 -1
  30. data/lib/rubocop/cop/rails/content_tag.rb +5 -6
  31. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +16 -3
  32. data/lib/rubocop/cop/rails/date.rb +15 -11
  33. data/lib/rubocop/cop/rails/delegate.rb +19 -8
  34. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +1 -1
  35. data/lib/rubocop/cop/rails/deprecated_active_model_errors_methods.rb +18 -14
  36. data/lib/rubocop/cop/rails/dot_separated_keys.rb +2 -2
  37. data/lib/rubocop/cop/rails/duration_arithmetic.rb +3 -3
  38. data/lib/rubocop/cop/rails/dynamic_find_by.rb +25 -13
  39. data/lib/rubocop/cop/rails/eager_evaluation_log_message.rb +5 -1
  40. data/lib/rubocop/cop/rails/enum_hash.rb +1 -1
  41. data/lib/rubocop/cop/rails/enum_uniqueness.rb +2 -5
  42. data/lib/rubocop/cop/rails/environment_comparison.rb +2 -3
  43. data/lib/rubocop/cop/rails/file_path.rb +154 -27
  44. data/lib/rubocop/cop/rails/find_by_id.rb +2 -2
  45. data/lib/rubocop/cop/rails/find_each.rb +15 -5
  46. data/lib/rubocop/cop/rails/freeze_time.rb +79 -0
  47. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +4 -6
  48. data/lib/rubocop/cop/rails/helper_instance_variable.rb +1 -1
  49. data/lib/rubocop/cop/rails/http_positional_arguments.rb +22 -11
  50. data/lib/rubocop/cop/rails/http_status.rb +6 -11
  51. data/lib/rubocop/cop/rails/i18n_lazy_lookup.rb +2 -0
  52. data/lib/rubocop/cop/rails/i18n_locale_texts.rb +7 -3
  53. data/lib/rubocop/cop/rails/ignored_columns_assignment.rb +50 -0
  54. data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +23 -12
  55. data/lib/rubocop/cop/rails/index_by.rb +1 -1
  56. data/lib/rubocop/cop/rails/index_with.rb +1 -1
  57. data/lib/rubocop/cop/rails/inverse_of.rb +3 -9
  58. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +21 -15
  59. data/lib/rubocop/cop/rails/link_to_blank.rb +1 -4
  60. data/lib/rubocop/cop/rails/mailer_name.rb +4 -4
  61. data/lib/rubocop/cop/rails/migration_class_name.rb +1 -1
  62. data/lib/rubocop/cop/rails/negate_include.rb +1 -1
  63. data/lib/rubocop/cop/rails/not_null_column.rb +9 -6
  64. data/lib/rubocop/cop/rails/output.rb +6 -8
  65. data/lib/rubocop/cop/rails/output_safety.rb +5 -1
  66. data/lib/rubocop/cop/rails/pluck.rb +44 -12
  67. data/lib/rubocop/cop/rails/pluck_id.rb +1 -1
  68. data/lib/rubocop/cop/rails/pluralization_grammar.rb +1 -2
  69. data/lib/rubocop/cop/rails/presence.rb +21 -12
  70. data/lib/rubocop/cop/rails/present.rb +8 -11
  71. data/lib/rubocop/cop/rails/rake_environment.rb +2 -2
  72. data/lib/rubocop/cop/rails/read_write_attribute.rb +1 -1
  73. data/lib/rubocop/cop/rails/redundant_allow_nil.rb +5 -7
  74. data/lib/rubocop/cop/rails/redundant_foreign_key.rb +2 -2
  75. data/lib/rubocop/cop/rails/redundant_presence_validation_on_belongs_to.rb +3 -3
  76. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +30 -26
  77. data/lib/rubocop/cop/rails/reflection_class_name.rb +34 -1
  78. data/lib/rubocop/cop/rails/refute_methods.rb +1 -6
  79. data/lib/rubocop/cop/rails/relative_date_constant.rb +4 -7
  80. data/lib/rubocop/cop/rails/request_referer.rb +1 -2
  81. data/lib/rubocop/cop/rails/require_dependency.rb +1 -1
  82. data/lib/rubocop/cop/rails/response_parsed_body.rb +57 -0
  83. data/lib/rubocop/cop/rails/reversible_migration.rb +14 -62
  84. data/lib/rubocop/cop/rails/reversible_migration_method_definition.rb +1 -2
  85. data/lib/rubocop/cop/rails/root_join_chain.rb +1 -1
  86. data/lib/rubocop/cop/rails/root_pathname_methods.rb +238 -0
  87. data/lib/rubocop/cop/rails/safe_navigation.rb +1 -1
  88. data/lib/rubocop/cop/rails/safe_navigation_with_blank.rb +1 -3
  89. data/lib/rubocop/cop/rails/save_bang.rb +10 -22
  90. data/lib/rubocop/cop/rails/short_i18n.rb +2 -5
  91. data/lib/rubocop/cop/rails/skips_model_validations.rb +2 -3
  92. data/lib/rubocop/cop/rails/squished_sql_heredocs.rb +9 -7
  93. data/lib/rubocop/cop/rails/three_state_boolean_column.rb +71 -0
  94. data/lib/rubocop/cop/rails/time_zone.rb +27 -25
  95. data/lib/rubocop/cop/rails/time_zone_assignment.rb +1 -1
  96. data/lib/rubocop/cop/rails/to_s_with_argument.rb +78 -0
  97. data/lib/rubocop/cop/rails/top_level_hash_with_indifferent_access.rb +49 -0
  98. data/lib/rubocop/cop/rails/transaction_exit_statement.rb +8 -3
  99. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +3 -6
  100. data/lib/rubocop/cop/rails/unique_validation_without_index.rb +22 -19
  101. data/lib/rubocop/cop/rails/unknown_env.rb +2 -4
  102. data/lib/rubocop/cop/rails/unused_ignored_columns.rb +6 -1
  103. data/lib/rubocop/cop/rails/validation.rb +4 -12
  104. data/lib/rubocop/cop/rails/where_equals.rb +1 -1
  105. data/lib/rubocop/cop/rails/where_exists.rb +1 -1
  106. data/lib/rubocop/cop/rails/where_missing.rb +118 -0
  107. data/lib/rubocop/cop/rails/where_not.rb +1 -1
  108. data/lib/rubocop/cop/rails/where_not_with_multiple_conditions.rb +55 -0
  109. data/lib/rubocop/cop/rails_cops.rb +12 -0
  110. data/lib/rubocop/rails/schema_loader/schema.rb +4 -4
  111. data/lib/rubocop/rails/version.rb +1 -1
  112. data/lib/rubocop/rails.rb +1 -1
  113. data/lib/rubocop-rails.rb +11 -0
  114. metadata +19 -9
  115. data/bin/console +0 -11
  116. data/bin/setup +0 -7
@@ -143,7 +143,7 @@ module RuboCop
143
143
  def_node_matcher :belongs_to_without_fk?, <<~PATTERN
144
144
  {
145
145
  (send nil? :belongs_to (sym %1)) # belongs_to :user
146
- (send nil? :belongs_to (sym %1) !hash) # belongs_to :user, -> { not_deleted }
146
+ (send nil? :belongs_to (sym %1) !hash ...) # belongs_to :user, -> { not_deleted }
147
147
  (send nil? :belongs_to (sym %1) !(hash <(pair (sym :foreign_key) _) ...>))
148
148
  }
149
149
  PATTERN
@@ -217,7 +217,7 @@ module RuboCop
217
217
  keys.each do |key|
218
218
  key_node = node.arguments.find { |arg| arg.value == key }
219
219
  key_range = range_with_surrounding_space(
220
- range: range_with_surrounding_comma(key_node.source_range, :right),
220
+ range_with_surrounding_comma(key_node.source_range, :right),
221
221
  side: :right
222
222
  )
223
223
  corrector.remove(key_range)
@@ -226,7 +226,7 @@ module RuboCop
226
226
 
227
227
  def remove_presence_option(corrector, presence)
228
228
  range = range_with_surrounding_comma(
229
- range_with_surrounding_space(range: presence.source_range, side: :left),
229
+ range_with_surrounding_space(presence.source_range, side: :left),
230
230
  :left
231
231
  )
232
232
  corrector.remove(range)
@@ -60,15 +60,6 @@ module RuboCop
60
60
 
61
61
  MSG = 'Redundant receiver in `with_options`.'
62
62
 
63
- def_node_matcher :with_options?, <<~PATTERN
64
- (block
65
- (send nil? :with_options
66
- (...))
67
- (args
68
- $_arg)
69
- $_body)
70
- PATTERN
71
-
72
63
  def_node_search :all_block_nodes_in, <<~PATTERN
73
64
  (block ...)
74
65
  PATTERN
@@ -78,29 +69,42 @@ module RuboCop
78
69
  PATTERN
79
70
 
80
71
  def on_block(node)
81
- with_options?(node) do |arg, body|
82
- return if body.nil?
83
- return unless all_block_nodes_in(body).count.zero?
84
-
85
- send_nodes = all_send_nodes_in(body)
86
-
87
- if send_nodes.all? { |n| same_value?(arg, n.receiver) }
88
- send_nodes.each do |send_node|
89
- receiver = send_node.receiver
90
- add_offense(receiver.source_range) do |corrector|
91
- autocorrect(corrector, send_node)
92
- end
93
- end
72
+ return unless node.method?(:with_options)
73
+ return unless (body = node.body)
74
+ return unless all_block_nodes_in(body).count.zero?
75
+
76
+ send_nodes = all_send_nodes_in(body)
77
+ return unless redundant_receiver?(send_nodes, node)
78
+
79
+ send_nodes.each do |send_node|
80
+ receiver = send_node.receiver
81
+ add_offense(receiver.source_range) do |corrector|
82
+ autocorrect(corrector, send_node, node)
94
83
  end
95
84
  end
96
85
  end
97
86
 
87
+ alias on_numblock on_block
88
+
98
89
  private
99
90
 
100
- def autocorrect(corrector, node)
101
- corrector.remove(node.receiver.source_range)
102
- corrector.remove(node.loc.dot)
103
- corrector.remove(block_argument_range(node))
91
+ def autocorrect(corrector, send_node, node)
92
+ corrector.remove(send_node.receiver)
93
+ corrector.remove(send_node.loc.dot)
94
+ corrector.remove(block_argument_range(send_node)) unless node.numblock_type?
95
+ end
96
+
97
+ def redundant_receiver?(send_nodes, node)
98
+ proc = if node.numblock_type?
99
+ ->(n) { n.receiver.lvar_type? && n.receiver.source == '_1' }
100
+ else
101
+ return false if node.arguments.empty?
102
+
103
+ arg = node.arguments.first
104
+ ->(n) { same_value?(arg, n.receiver) }
105
+ end
106
+
107
+ send_nodes.all?(&proc)
104
108
  end
105
109
 
106
110
  def block_argument_range(node)
@@ -18,6 +18,8 @@ module RuboCop
18
18
  # # good
19
19
  # has_many :accounts, class_name: 'Account'
20
20
  class ReflectionClassName < Base
21
+ extend AutoCorrector
22
+
21
23
  MSG = 'Use a string value for `class_name`.'
22
24
  RESTRICT_ON_SEND = %i[has_many has_one belongs_to].freeze
23
25
  ALLOWED_REFLECTION_CLASS_TYPES = %i[dstr str sym].freeze
@@ -32,14 +34,37 @@ module RuboCop
32
34
  (pair (sym :class_name) #reflection_class_value?)
33
35
  PATTERN
34
36
 
37
+ def_node_matcher :const_or_string, <<~PATTERN
38
+ {$(const nil? _) (send $(const nil? _) :name) (send $(const nil? _) :to_s)}
39
+ PATTERN
40
+
35
41
  def on_send(node)
36
42
  association_with_reflection(node) do |reflection_class_name|
37
- add_offense(reflection_class_name.loc.expression)
43
+ return if reflection_class_name.value.send_type? && reflection_class_name.value.receiver.nil?
44
+ return if reflection_class_name.value.lvar_type? && str_assigned?(reflection_class_name)
45
+
46
+ add_offense(reflection_class_name.source_range) do |corrector|
47
+ autocorrect(corrector, reflection_class_name)
48
+ end
38
49
  end
39
50
  end
40
51
 
41
52
  private
42
53
 
54
+ def str_assigned?(reflection_class_name)
55
+ lvar = reflection_class_name.value.source
56
+
57
+ reflection_class_name.ancestors.each do |nodes|
58
+ return true if nodes.each_child_node(:lvasgn).detect do |node|
59
+ lhs, rhs = *node
60
+
61
+ lhs.to_s == lvar && ALLOWED_REFLECTION_CLASS_TYPES.include?(rhs.type)
62
+ end
63
+ end
64
+
65
+ false
66
+ end
67
+
43
68
  def reflection_class_value?(class_value)
44
69
  if class_value.send_type?
45
70
  !class_value.method?(:to_s) || class_value.receiver&.const_type?
@@ -47,6 +72,14 @@ module RuboCop
47
72
  !ALLOWED_REFLECTION_CLASS_TYPES.include?(class_value.type)
48
73
  end
49
74
  end
75
+
76
+ def autocorrect(corrector, class_config)
77
+ class_value = class_config.value
78
+ replacement = const_or_string(class_value)
79
+ return unless replacement.present?
80
+
81
+ corrector.replace(class_value, replacement.source.inspect)
82
+ end
50
83
  end
51
84
  end
52
85
  end
@@ -3,7 +3,6 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Rails
6
- #
7
6
  # Use `assert_not` methods instead of `refute` methods.
8
7
  #
9
8
  # @example EnforcedStyle: assert_not (default)
@@ -81,11 +80,7 @@ module RuboCop
81
80
  end
82
81
 
83
82
  def offense_message(method_name)
84
- format(
85
- MSG,
86
- bad_method: method_name,
87
- good_method: convert_good_method(method_name)
88
- )
83
+ format(MSG, bad_method: method_name, good_method: convert_good_method(method_name))
89
84
  end
90
85
 
91
86
  def convert_good_method(bad_method)
@@ -34,8 +34,7 @@ module RuboCop
34
34
  include RangeHelp
35
35
  extend AutoCorrector
36
36
 
37
- MSG = 'Do not assign `%<method_name>s` to constants as it ' \
38
- 'will be evaluated only once.'
37
+ MSG = 'Do not assign `%<method_name>s` to constants as it will be evaluated only once.'
39
38
  RELATIVE_DATE_METHODS = %i[since from_now after ago until before yesterday tomorrow].to_set.freeze
40
39
 
41
40
  def on_casgn(node)
@@ -77,11 +76,9 @@ module RuboCop
77
76
  return unless scope.nil?
78
77
 
79
78
  indent = ' ' * node.loc.column
80
- new_code = ["def self.#{const_name.downcase}",
81
- "#{indent}#{value.source}",
82
- 'end'].join("\n#{indent}")
79
+ new_code = ["def self.#{const_name.downcase}", "#{indent}#{value.source}", 'end'].join("\n#{indent}")
83
80
 
84
- corrector.replace(node.source_range, new_code)
81
+ corrector.replace(node, new_code)
85
82
  end
86
83
 
87
84
  def message(method_name)
@@ -89,7 +86,7 @@ module RuboCop
89
86
  end
90
87
 
91
88
  def offense_range(name, value)
92
- range_between(name.loc.expression.begin_pos, value.loc.expression.end_pos)
89
+ range_between(name.source_range.begin_pos, value.source_range.end_pos)
93
90
  end
94
91
 
95
92
  def nested_relative_date(node, &callback)
@@ -23,8 +23,7 @@ module RuboCop
23
23
  include ConfigurableEnforcedStyle
24
24
  extend AutoCorrector
25
25
 
26
- MSG = 'Use `request.%<prefer>s` instead of ' \
27
- '`request.%<current>s`.'
26
+ MSG = 'Use `request.%<prefer>s` instead of `request.%<current>s`.'
28
27
  RESTRICT_ON_SEND = %i[referer referrer].freeze
29
28
 
30
29
  def_node_matcher :referer?, <<~PATTERN
@@ -26,7 +26,7 @@ module RuboCop
26
26
  RESTRICT_ON_SEND = %i[require_dependency].freeze
27
27
 
28
28
  def_node_matcher :require_dependency_call?, <<~PATTERN
29
- (send {nil? (const _ :Kernel)} :require_dependency _)
29
+ (send {nil? (const {nil? cbase} :Kernel)} :require_dependency _)
30
30
  PATTERN
31
31
 
32
32
  def on_send(node)
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Rails
6
+ # Prefer `response.parsed_body` to `JSON.parse(response.body)`.
7
+ #
8
+ # @safety
9
+ # This cop is unsafe because Content-Type may not be `application/json`. For example, the proprietary
10
+ # Content-Type provided by corporate entities such as `application/vnd.github+json` is not supported at
11
+ # `response.parsed_body` by default, so you still have to use `JSON.parse(response.body)` there.
12
+ #
13
+ # @example
14
+ # # bad
15
+ # JSON.parse(response.body)
16
+ #
17
+ # # good
18
+ # response.parsed_body
19
+ class ResponseParsedBody < Base
20
+ extend AutoCorrector
21
+ extend TargetRailsVersion
22
+
23
+ MSG = 'Prefer `response.parsed_body` to `JSON.parse(response.body)`.'
24
+
25
+ RESTRICT_ON_SEND = %i[parse].freeze
26
+
27
+ minimum_target_rails_version 5.0
28
+
29
+ # @!method json_parse_response_body?(node)
30
+ def_node_matcher :json_parse_response_body?, <<~PATTERN
31
+ (send
32
+ (const {nil? cbase} :JSON)
33
+ :parse
34
+ (send
35
+ (send nil? :response)
36
+ :body
37
+ )
38
+ )
39
+ PATTERN
40
+
41
+ def on_send(node)
42
+ return unless json_parse_response_body?(node)
43
+
44
+ add_offense(node) do |corrector|
45
+ autocorrect(corrector, node)
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def autocorrect(corrector, node)
52
+ corrector.replace(node, 'response.parsed_body')
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -16,23 +16,15 @@ module RuboCop
16
16
  #
17
17
  # # good
18
18
  # def change
19
- # create_table :users do |t|
20
- # t.string :name
19
+ # change_table :users do |t|
20
+ # t.remove :name, :string
21
21
  # end
22
22
  # end
23
23
  #
24
24
  # # good
25
25
  # def change
26
- # reversible do |dir|
27
- # change_table :users do |t|
28
- # dir.up do
29
- # t.column :name, :string
30
- # end
31
- #
32
- # dir.down do
33
- # t.remove :name
34
- # end
35
- # end
26
+ # create_table :users do |t|
27
+ # t.string :name
36
28
  # end
37
29
  # end
38
30
  #
@@ -114,21 +106,6 @@ module RuboCop
114
106
  # end
115
107
  # end
116
108
  #
117
- # # good
118
- # def change
119
- # reversible do |dir|
120
- # change_table :users do |t|
121
- # dir.up do
122
- # t.change :price, :string
123
- # end
124
- #
125
- # dir.down do
126
- # t.change :price, :integer
127
- # end
128
- # end
129
- # end
130
- # end
131
- #
132
109
  # @example
133
110
  # # remove_columns
134
111
  #
@@ -173,8 +150,6 @@ module RuboCop
173
150
  # def change
174
151
  # remove_index :users, column: :email
175
152
  # end
176
- #
177
- # @see https://api.rubyonrails.org/classes/ActiveRecord/Migration/CommandRecorder.html
178
153
  class ReversibleMigration < Base
179
154
  include MigrationsHelper
180
155
 
@@ -229,6 +204,8 @@ module RuboCop
229
204
  check_change_table_node(node.send_node, node.body)
230
205
  end
231
206
 
207
+ alias on_numblock on_block
208
+
232
209
  private
233
210
 
234
211
  def check_irreversible_schema_statement_node(node)
@@ -240,10 +217,7 @@ module RuboCop
240
217
  def check_drop_table_node(node)
241
218
  drop_table_call(node) do
242
219
  unless node.parent.block_type? || node.last_argument.block_pass_type?
243
- add_offense(
244
- node,
245
- message: format(MSG, action: 'drop_table(without block)')
246
- )
220
+ add_offense(node, message: format(MSG, action: 'drop_table(without block)'))
247
221
  end
248
222
  end
249
223
  end
@@ -251,22 +225,12 @@ module RuboCop
251
225
  def check_reversible_hash_node(node)
252
226
  return if reversible_change_table_call?(node)
253
227
 
254
- add_offense(
255
- node,
256
- message: format(
257
- MSG, action: "#{node.method_name}(without :from and :to)"
258
- )
259
- )
228
+ add_offense(node, message: format(MSG, action: "#{node.method_name}(without :from and :to)"))
260
229
  end
261
230
 
262
231
  def check_remove_column_node(node)
263
232
  remove_column_call(node) do |args|
264
- if args.to_a.size < 3
265
- add_offense(
266
- node,
267
- message: format(MSG, action: 'remove_column(without type)')
268
- )
269
- end
233
+ add_offense(node, message: format(MSG, action: 'remove_column(without type)')) if args.to_a.size < 3
270
234
  end
271
235
  end
272
236
 
@@ -295,10 +259,7 @@ module RuboCop
295
259
  unless all_hash_key?(args, :type) && target_rails_version >= 6.1
296
260
  action = target_rails_version >= 6.1 ? 'remove_columns(without type)' : 'remove_columns'
297
261
 
298
- add_offense(
299
- node,
300
- message: format(MSG, action: action)
301
- )
262
+ add_offense(node, message: format(MSG, action: action))
302
263
  end
303
264
  end
304
265
  end
@@ -306,18 +267,14 @@ module RuboCop
306
267
  def check_remove_index_node(node)
307
268
  remove_index_call(node) do |args|
308
269
  if args.hash_type? && !all_hash_key?(args, :column)
309
- add_offense(
310
- node,
311
- message: format(MSG, action: 'remove_index(without column)')
312
- )
270
+ add_offense(node, message: format(MSG, action: 'remove_index(without column)'))
313
271
  end
314
272
  end
315
273
  end
316
274
 
317
275
  def check_change_table_offense(receiver, node)
318
276
  method_name = node.method_name
319
- return if receiver != node.receiver &&
320
- reversible_change_table_call?(node)
277
+ return if receiver != node.receiver && reversible_change_table_call?(node)
321
278
 
322
279
  action = if method_name == :remove
323
280
  target_rails_version >= 6.1 ? 't.remove (without type)' : 't.remove'
@@ -325,10 +282,7 @@ module RuboCop
325
282
  "change_table(with #{method_name})"
326
283
  end
327
284
 
328
- add_offense(
329
- node,
330
- message: format(MSG, action: action)
331
- )
285
+ add_offense(node, message: format(MSG, action: action))
332
286
  end
333
287
 
334
288
  def reversible_change_table_call?(node)
@@ -353,9 +307,7 @@ module RuboCop
353
307
 
354
308
  def within_reversible_or_up_only_block?(node)
355
309
  node.each_ancestor(:block).any? do |ancestor|
356
- (ancestor.block_type? &&
357
- ancestor.send_node.method?(:reversible)) ||
358
- ancestor.send_node.method?(:up_only)
310
+ (ancestor.block_type? && ancestor.send_node.method?(:reversible)) || ancestor.send_node.method?(:up_only)
359
311
  end
360
312
  end
361
313
 
@@ -45,8 +45,7 @@ module RuboCop
45
45
  class ReversibleMigrationMethodDefinition < Base
46
46
  include MigrationsHelper
47
47
 
48
- MSG = 'Migrations must contain either a `change` method, or ' \
49
- 'both an `up` and a `down` method.'
48
+ MSG = 'Migrations must contain either a `change` method, or both an `up` and a `down` method.'
50
49
 
51
50
  def_node_matcher :change_method?, <<~PATTERN
52
51
  `(def :change (args) _)
@@ -39,7 +39,7 @@ module RuboCop
39
39
  def on_send(node)
40
40
  evidence(node) do |rails_node, args|
41
41
  add_offense(node, message: format(MSG, root: rails_node.source)) do |corrector|
42
- range = range_between(rails_node.loc.selector.end_pos, node.loc.expression.end_pos)
42
+ range = range_between(rails_node.loc.selector.end_pos, node.source_range.end_pos)
43
43
  replacement = ".join(#{args.map(&:source).join(', ')})"
44
44
 
45
45
  corrector.replace(range, replacement)