rubocop-rails 2.7.0 → 2.9.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 (95) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +16 -0
  3. data/config/default.yml +78 -4
  4. data/lib/rubocop/cop/mixin/active_record_helper.rb +5 -3
  5. data/lib/rubocop/cop/mixin/enforce_superclass.rb +40 -0
  6. data/lib/rubocop/cop/mixin/index_method.rb +25 -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 +19 -16
  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 +91 -0
  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 +17 -17
  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 +13 -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 +5 -4
  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 +17 -18
  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 +4 -7
  40. data/lib/rubocop/cop/rails/helper_instance_variable.rb +30 -2
  41. data/lib/rubocop/cop/rails/http_positional_arguments.rb +25 -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 +11 -2
  45. data/lib/rubocop/cop/rails/index_with.rb +11 -2
  46. data/lib/rubocop/cop/rails/inquiry.rb +7 -2
  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 +16 -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 +52 -0
  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 +39 -5
  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 +9 -11
  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 +4 -3
  70. data/lib/rubocop/cop/rails/refute_methods.rb +9 -10
  71. data/lib/rubocop/cop/rails/relative_date_constant.rb +20 -9
  72. data/lib/rubocop/cop/rails/render_inline.rb +5 -12
  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 +82 -7
  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 +19 -22
  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 +82 -0
  83. data/lib/rubocop/cop/rails/time_zone.rb +22 -20
  84. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +6 -6
  85. data/lib/rubocop/cop/rails/unique_validation_without_index.rb +18 -8
  86. data/lib/rubocop/cop/rails/unknown_env.rb +15 -4
  87. data/lib/rubocop/cop/rails/validation.rb +15 -14
  88. data/lib/rubocop/cop/rails/where_equals.rb +98 -0
  89. data/lib/rubocop/cop/rails/where_exists.rb +74 -16
  90. data/lib/rubocop/cop/rails/where_not.rb +97 -0
  91. data/lib/rubocop/cop/rails_cops.rb +8 -0
  92. data/lib/rubocop/rails/schema_loader.rb +4 -4
  93. data/lib/rubocop/rails/schema_loader/schema.rb +5 -5
  94. data/lib/rubocop/rails/version.rb +5 -1
  95. metadata +23 -9
@@ -17,11 +17,12 @@ module RuboCop
17
17
  #
18
18
  # # good
19
19
  # enum status: [:active, :archived]
20
- class EnumUniqueness < Cop
20
+ class EnumUniqueness < Base
21
21
  include Duplication
22
22
 
23
23
  MSG = 'Duplicate value `%<value>s` found in `%<enum>s` ' \
24
24
  'enum declaration.'
25
+ RESTRICT_ON_SEND = %i[enum].freeze
25
26
 
26
27
  def_node_matcher :enum?, <<~PATTERN
27
28
  (send nil? :enum (hash $...))
@@ -15,12 +15,16 @@ module RuboCop
15
15
  #
16
16
  # # good
17
17
  # Rails.env.production?
18
- class EnvironmentComparison < Cop
18
+ class EnvironmentComparison < Base
19
+ extend AutoCorrector
20
+
19
21
  MSG = 'Favor `%<bang>sRails.env.%<env>s?` over `%<source>s`.'
20
22
 
21
23
  SYM_MSG = 'Do not compare `Rails.env` with a symbol, it will always ' \
22
24
  'evaluate to `false`.'
23
25
 
26
+ RESTRICT_ON_SEND = %i[== !=].freeze
27
+
24
28
  def_node_matcher :comparing_str_env_with_rails_env_on_lhs?, <<~PATTERN
25
29
  (send
26
30
  (send (const {nil? cbase} :Rails) :env)
@@ -62,28 +66,28 @@ module RuboCop
62
66
  comparing_str_env_with_rails_env_on_rhs?(node))
63
67
  env, = *env_node
64
68
  bang = node.method?(:!=) ? '!' : ''
69
+ message = format(MSG, bang: bang, env: env, source: node.source)
65
70
 
66
- add_offense(node, message: format(
67
- MSG, bang: bang, env: env, source: node.source
68
- ))
69
- end
70
-
71
- if comparing_sym_env_with_rails_env_on_lhs?(node) ||
72
- comparing_sym_env_with_rails_env_on_rhs?(node)
73
- add_offense(node, message: SYM_MSG)
71
+ add_offense(node, message: message) do |corrector|
72
+ autocorrect(corrector, node)
73
+ end
74
74
  end
75
- end
76
75
 
77
- def autocorrect(node)
78
- lambda do |corrector|
79
- replacement = build_predicate_method(node)
76
+ return unless comparing_sym_env_with_rails_env_on_lhs?(node) || comparing_sym_env_with_rails_env_on_rhs?(node)
80
77
 
81
- corrector.replace(node.source_range, replacement)
78
+ add_offense(node, message: SYM_MSG) do |corrector|
79
+ autocorrect(corrector, node)
82
80
  end
83
81
  end
84
82
 
85
83
  private
86
84
 
85
+ def autocorrect(corrector, node)
86
+ replacement = build_predicate_method(node)
87
+
88
+ corrector.replace(node.source_range, replacement)
89
+ end
90
+
87
91
  def build_predicate_method(node)
88
92
  if rails_env_on_lhs?(node)
89
93
  build_predicate_method_for_rails_env_on_lhs(node)
@@ -23,27 +23,21 @@ module RuboCop
23
23
  #
24
24
  # # good
25
25
  # raise 'a bad error has happened'
26
- class Exit < Cop
26
+ class Exit < Base
27
27
  include ConfigurableEnforcedStyle
28
28
 
29
29
  MSG = 'Do not use `exit` in Rails applications.'
30
- TARGET_METHODS = %i[exit exit!].freeze
30
+ RESTRICT_ON_SEND = %i[exit exit!].freeze
31
31
  EXPLICIT_RECEIVERS = %i[Kernel Process].freeze
32
32
 
33
33
  def on_send(node)
34
- add_offense(node, location: :selector) if offending_node?(node)
34
+ add_offense(node.loc.selector) if offending_node?(node)
35
35
  end
36
36
 
37
37
  private
38
38
 
39
39
  def offending_node?(node)
40
- right_method_name?(node.method_name) &&
41
- right_argument_count?(node.arguments) &&
42
- right_receiver?(node.receiver)
43
- end
44
-
45
- def right_method_name?(method_name)
46
- TARGET_METHODS.include?(method_name)
40
+ right_argument_count?(node.arguments) && right_receiver?(node.receiver)
47
41
  end
48
42
 
49
43
  # More than 1 argument likely means it is a different
@@ -25,7 +25,7 @@ module RuboCop
25
25
  # # good
26
26
  # Rails.root.join('app/models/goober')
27
27
  #
28
- class FilePath < Cop
28
+ class FilePath < Base
29
29
  include ConfigurableEnforcedStyle
30
30
  include RangeHelp
31
31
 
@@ -33,6 +33,7 @@ module RuboCop
33
33
  'instead.'
34
34
  MSG_ARGUMENTS = 'Please use `Rails.root.join(\'path\', \'to\')` ' \
35
35
  'instead.'
36
+ RESTRICT_ON_SEND = %i[join].freeze
36
37
 
37
38
  def_node_matcher :file_join_nodes?, <<~PATTERN
38
39
  (send (const nil? :File) :join ...)
@@ -90,17 +91,17 @@ module RuboCop
90
91
  end
91
92
 
92
93
  def string_with_slash?(node)
93
- node.str_type? && node.source.match?(%r{/})
94
+ node.str_type? && node.source.include?('/')
94
95
  end
95
96
 
96
97
  def register_offense(node)
97
98
  line_range = node.loc.column...node.loc.last_column
98
99
  source_range = source_range(processed_source.buffer, node.first_line,
99
100
  line_range)
100
- add_offense(node, location: source_range)
101
+ add_offense(source_range)
101
102
  end
102
103
 
103
- def message(_node)
104
+ def message(_range)
104
105
  format(style == :arguments ? MSG_ARGUMENTS : MSG_SLASHES)
105
106
  end
106
107
  end
@@ -13,11 +13,12 @@ module RuboCop
13
13
  #
14
14
  # # good
15
15
  # User.find_by(name: 'Bruce')
16
- class FindBy < Cop
16
+ class FindBy < Base
17
17
  include RangeHelp
18
+ extend AutoCorrector
18
19
 
19
20
  MSG = 'Use `find_by` instead of `where.%<method>s`.'
20
- TARGET_SELECTORS = %i[first take].freeze
21
+ RESTRICT_ON_SEND = %i[first take].freeze
21
22
 
22
23
  def_node_matcher :where_first?, <<~PATTERN
23
24
  (send ({send csend} _ :where ...) {:first :take})
@@ -26,28 +27,27 @@ module RuboCop
26
27
  def on_send(node)
27
28
  return unless where_first?(node)
28
29
 
29
- range = range_between(node.receiver.loc.selector.begin_pos,
30
- node.loc.selector.end_pos)
30
+ range = range_between(node.receiver.loc.selector.begin_pos, node.loc.selector.end_pos)
31
31
 
32
- add_offense(node, location: range,
33
- message: format(MSG, method: node.method_name))
32
+ add_offense(range, message: format(MSG, method: node.method_name)) do |corrector|
33
+ autocorrect(corrector, node)
34
+ end
34
35
  end
35
36
  alias on_csend on_send
36
37
 
37
- def autocorrect(node)
38
+ private
39
+
40
+ def autocorrect(corrector, node)
38
41
  # Don't autocorrect where(...).first, because it can return different
39
42
  # results from find_by. (They order records differently, so the
40
43
  # 'first' record can be different.)
41
44
  return if node.method?(:first)
42
45
 
43
46
  where_loc = node.receiver.loc.selector
44
- first_loc = range_between(node.loc.dot.begin_pos,
45
- node.loc.selector.end_pos)
47
+ first_loc = range_between(node.loc.dot.begin_pos, node.loc.selector.end_pos)
46
48
 
47
- lambda do |corrector|
48
- corrector.replace(where_loc, 'find_by')
49
- corrector.replace(first_loc, '')
50
- end
49
+ corrector.replace(where_loc, 'find_by')
50
+ corrector.replace(first_loc, '')
51
51
  end
52
52
  end
53
53
  end
@@ -16,10 +16,12 @@ module RuboCop
16
16
  # # good
17
17
  # User.find(id)
18
18
  #
19
- class FindById < Cop
19
+ class FindById < Base
20
20
  include RangeHelp
21
+ extend AutoCorrector
21
22
 
22
23
  MSG = 'Use `%<good_method>s` instead of `%<bad_method>s`.'
24
+ RESTRICT_ON_SEND = %i[take! find_by_id! find_by!].freeze
23
25
 
24
26
  def_node_matcher :where_take?, <<~PATTERN
25
27
  (send
@@ -38,41 +40,30 @@ module RuboCop
38
40
  def on_send(node)
39
41
  where_take?(node) do |where, id_value|
40
42
  range = where_take_offense_range(node, where)
41
-
42
- good_method = build_good_method(id_value)
43
43
  bad_method = build_where_take_bad_method(id_value)
44
- message = format(MSG, good_method: good_method, bad_method: bad_method)
45
44
 
46
- add_offense(node, location: range, message: message)
45
+ register_offense(range, id_value, bad_method)
47
46
  end
48
47
 
49
48
  find_by?(node) do |id_value|
50
49
  range = find_by_offense_range(node)
51
-
52
- good_method = build_good_method(id_value)
53
50
  bad_method = build_find_by_bad_method(node, id_value)
54
- message = format(MSG, good_method: good_method, bad_method: bad_method)
55
51
 
56
- add_offense(node, location: range, message: message)
52
+ register_offense(range, id_value, bad_method)
57
53
  end
58
54
  end
59
55
 
60
- def autocorrect(node)
61
- if (matches = where_take?(node))
62
- where, id_value = *matches
63
- range = where_take_offense_range(node, where)
64
- elsif (id_value = find_by?(node))
65
- range = find_by_offense_range(node)
66
- end
56
+ private
57
+
58
+ def register_offense(range, id_value, bad_method)
59
+ good_method = build_good_method(id_value)
60
+ message = format(MSG, good_method: good_method, bad_method: bad_method)
67
61
 
68
- lambda do |corrector|
69
- replacement = build_good_method(id_value)
70
- corrector.replace(range, replacement)
62
+ add_offense(range, message: message) do |corrector|
63
+ corrector.replace(range, good_method)
71
64
  end
72
65
  end
73
66
 
74
- private
75
-
76
67
  def where_take_offense_range(node, where)
77
68
  range_between(where.loc.selector.begin_pos, node.loc.expression.end_pos)
78
69
  end
@@ -12,38 +12,37 @@ module RuboCop
12
12
  #
13
13
  # # good
14
14
  # User.all.find_each
15
- class FindEach < Cop
15
+ #
16
+ # @example IgnoredMethods: ['order']
17
+ # # good
18
+ # User.order(:foo).each
19
+ class FindEach < Base
20
+ extend AutoCorrector
21
+
16
22
  MSG = 'Use `find_each` instead of `each`.'
23
+ RESTRICT_ON_SEND = %i[each].freeze
17
24
 
18
25
  SCOPE_METHODS = %i[
19
26
  all eager_load includes joins left_joins left_outer_joins not preload
20
27
  references unscoped where
21
28
  ].freeze
22
- IGNORED_METHODS = %i[order limit select].freeze
23
29
 
24
30
  def on_send(node)
25
- return unless node.receiver&.send_type? &&
26
- node.method?(:each)
27
-
31
+ return unless node.receiver&.send_type?
28
32
  return unless SCOPE_METHODS.include?(node.receiver.method_name)
29
- return if method_chain(node).any? { |m| ignored_by_find_each?(m) }
33
+ return if ignored?(node)
30
34
 
31
- add_offense(node, location: :selector)
32
- end
33
-
34
- def autocorrect(node)
35
- ->(corrector) { corrector.replace(node.loc.selector, 'find_each') }
35
+ range = node.loc.selector
36
+ add_offense(range) do |corrector|
37
+ corrector.replace(range, 'find_each')
38
+ end
36
39
  end
37
40
 
38
41
  private
39
42
 
40
- def method_chain(node)
41
- node.each_node(:send).map(&:method_name)
42
- end
43
-
44
- def ignored_by_find_each?(relation_method)
45
- # Active Record's #find_each ignores various extra parameters
46
- IGNORED_METHODS.include?(relation_method)
43
+ def ignored?(node)
44
+ method_chain = node.each_node(:send).map(&:method_name)
45
+ (cop_config['IgnoredMethods'].map(&:to_sym) & method_chain).any?
47
46
  end
48
47
  end
49
48
  end
@@ -11,13 +11,14 @@ module RuboCop
11
11
  #
12
12
  # # good
13
13
  # # has_many :ingredients, through: :recipe_ingredients
14
- class HasAndBelongsToMany < Cop
14
+ class HasAndBelongsToMany < Base
15
15
  MSG = 'Prefer `has_many :through` to `has_and_belongs_to_many`.'
16
+ RESTRICT_ON_SEND = %i[has_and_belongs_to_many].freeze
16
17
 
17
18
  def on_send(node)
18
19
  return unless node.command?(:has_and_belongs_to_many)
19
20
 
20
- add_offense(node, location: :selector)
21
+ add_offense(node.loc.selector)
21
22
  end
22
23
  end
23
24
  end
@@ -20,8 +20,9 @@ module RuboCop
20
20
  # has_one :avatar, dependent: :destroy
21
21
  # has_many :patients, through: :appointments
22
22
  # end
23
- class HasManyOrHasOneDependent < Cop
23
+ class HasManyOrHasOneDependent < Base
24
24
  MSG = 'Specify a `:dependent` option.'
25
+ RESTRICT_ON_SEND = %i[has_many has_one].freeze
25
26
 
26
27
  def_node_search :active_resource_class?, <<~PATTERN
27
28
  (const (const nil? :ActiveResource) :Base)
@@ -52,14 +53,10 @@ module RuboCop
52
53
 
53
54
  def on_send(node)
54
55
  return if active_resource?(node.parent)
55
-
56
- unless association_without_options?(node)
57
- return if valid_options?(association_with_options?(node))
58
- end
59
-
56
+ return if !association_without_options?(node) && valid_options?(association_with_options?(node))
60
57
  return if valid_options_in_with_options_block?(node)
61
58
 
62
- add_offense(node, location: :selector)
59
+ add_offense(node.loc.selector)
63
60
  end
64
61
 
65
62
  private
@@ -13,6 +13,9 @@ module RuboCop
13
13
  # variable, consider moving the behaviour elsewhere, for
14
14
  # example to a model, decorator or presenter.
15
15
  #
16
+ # Provided that a class inherits `ActionView::Helpers::FormBuilder`,
17
+ # an offense will not be registered.
18
+ #
16
19
  # @example
17
20
  # # bad
18
21
  # def welcome_message
@@ -23,15 +26,40 @@ module RuboCop
23
26
  # def welcome_message(user)
24
27
  # "Hello #{user.name}"
25
28
  # end
26
- class HelperInstanceVariable < Cop
29
+ #
30
+ # # good
31
+ # class MyFormBuilder < ActionView::Helpers::FormBuilder
32
+ # @template.do_something
33
+ # end
34
+ class HelperInstanceVariable < Base
27
35
  MSG = 'Do not use instance variables in helpers.'
28
36
 
37
+ def_node_matcher :form_builder_class?, <<~PATTERN
38
+ (const
39
+ (const
40
+ (const nil? :ActionView) :Helpers) :FormBuilder)
41
+ PATTERN
42
+
29
43
  def on_ivar(node)
44
+ return if inherit_form_builder?(node)
45
+
30
46
  add_offense(node)
31
47
  end
32
48
 
33
49
  def on_ivasgn(node)
34
- add_offense(node, location: :name)
50
+ return if node.parent.or_asgn_type? || inherit_form_builder?(node)
51
+
52
+ add_offense(node.loc.name)
53
+ end
54
+
55
+ private
56
+
57
+ def inherit_form_builder?(node)
58
+ node.each_ancestor(:class) do |class_node|
59
+ return true if form_builder_class?(class_node.parent_class)
60
+ end
61
+
62
+ false
35
63
  end
36
64
  end
37
65
  end
@@ -16,7 +16,9 @@ module RuboCop
16
16
  #
17
17
  # # good
18
18
  # get :new, params: { user_id: 1 }
19
- class HttpPositionalArguments < Cop
19
+ # get :new, **options
20
+ class HttpPositionalArguments < Base
21
+ extend AutoCorrector
20
22
  extend TargetRailsVersion
21
23
 
22
24
  MSG = 'Use keyword arguments instead of ' \
@@ -24,36 +26,37 @@ module RuboCop
24
26
  KEYWORD_ARGS = %i[
25
27
  method params session body flash xhr as headers env to
26
28
  ].freeze
27
- HTTP_METHODS = %i[get post put patch delete head].freeze
29
+ RESTRICT_ON_SEND = %i[get post put patch delete head].freeze
28
30
 
29
31
  minimum_target_rails_version 5.0
30
32
 
31
33
  def_node_matcher :http_request?, <<~PATTERN
32
- (send nil? {#{HTTP_METHODS.map(&:inspect).join(' ')}} !nil? $_ ...)
34
+ (send nil? {#{RESTRICT_ON_SEND.map(&:inspect).join(' ')}} !nil? $_ ...)
35
+ PATTERN
36
+
37
+ def_node_matcher :kwsplat_hash?, <<~PATTERN
38
+ (hash (kwsplat _))
33
39
  PATTERN
34
40
 
35
41
  def on_send(node)
36
42
  http_request?(node) do |data|
37
43
  return unless needs_conversion?(data)
38
44
 
39
- add_offense(node, location: :selector,
40
- message: format(MSG, verb: node.method_name))
41
- end
42
- end
43
-
44
- # given a pre Rails 5 method: get :new, {user_id: @user.id}, {}
45
- #
46
- # @return lambda of auto correct procedure
47
- # the result should look like:
48
- # get :new, params: { user_id: @user.id }, session: {}
49
- # the http_method is the method used to call the controller
50
- # the controller node can be a symbol, method, object or string
51
- # that represents the path/action on the Rails controller
52
- # the data is the http parameters and environment sent in
53
- # the Rails 5 http call
54
- def autocorrect(node)
55
- lambda do |corrector|
56
- corrector.replace(node.loc.expression, correction(node))
45
+ message = format(MSG, verb: node.method_name)
46
+
47
+ add_offense(node.loc.selector, message: message) do |corrector|
48
+ # given a pre Rails 5 method: get :new, {user_id: @user.id}, {}
49
+ #
50
+ # @return lambda of auto correct procedure
51
+ # the result should look like:
52
+ # get :new, params: { user_id: @user.id }, session: {}
53
+ # the http_method is the method used to call the controller
54
+ # the controller node can be a symbol, method, object or string
55
+ # that represents the path/action on the Rails controller
56
+ # the data is the http parameters and environment sent in
57
+ # the Rails 5 http call
58
+ corrector.replace(node.loc.expression, correction(node))
59
+ end
57
60
  end
58
61
  end
59
62
 
@@ -61,6 +64,7 @@ module RuboCop
61
64
 
62
65
  def needs_conversion?(data)
63
66
  return true unless data.hash_type?
67
+ return false if kwsplat_hash?(data)
64
68
 
65
69
  data.each_pair.none? do |pair|
66
70
  special_keyword_arg?(pair.key) ||