rubocop-rails 2.7.1 → 2.10.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.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +18 -2
- data/config/default.yml +144 -6
- data/config/obsoletion.yml +7 -0
- data/lib/rubocop/cop/mixin/active_record_helper.rb +16 -3
- data/lib/rubocop/cop/mixin/enforce_superclass.rb +40 -0
- data/lib/rubocop/cop/mixin/index_method.rb +25 -11
- data/lib/rubocop/cop/rails/action_filter.rb +10 -14
- data/lib/rubocop/cop/rails/active_record_aliases.rb +13 -17
- data/lib/rubocop/cop/rails/active_record_callbacks_order.rb +19 -16
- data/lib/rubocop/cop/rails/active_record_override.rb +1 -1
- data/lib/rubocop/cop/rails/active_support_aliases.rb +12 -21
- data/lib/rubocop/cop/rails/after_commit_override.rb +91 -0
- data/lib/rubocop/cop/rails/application_controller.rb +3 -7
- data/lib/rubocop/cop/rails/application_job.rb +2 -1
- data/lib/rubocop/cop/rails/application_mailer.rb +2 -7
- data/lib/rubocop/cop/rails/application_record.rb +2 -7
- data/lib/rubocop/cop/rails/arel_star.rb +41 -0
- data/lib/rubocop/cop/rails/assert_not.rb +8 -10
- data/lib/rubocop/cop/rails/attribute_default_block_value.rb +90 -0
- data/lib/rubocop/cop/rails/belongs_to.rb +10 -19
- data/lib/rubocop/cop/rails/blank.rb +31 -27
- data/lib/rubocop/cop/rails/bulk_change_table.rb +1 -1
- data/lib/rubocop/cop/rails/content_tag.rb +34 -19
- data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +2 -1
- data/lib/rubocop/cop/rails/date.rb +10 -11
- data/lib/rubocop/cop/rails/default_scope.rb +11 -4
- data/lib/rubocop/cop/rails/delegate.rb +9 -9
- data/lib/rubocop/cop/rails/delegate_allow_blank.rb +7 -8
- data/lib/rubocop/cop/rails/dynamic_find_by.rb +15 -12
- data/lib/rubocop/cop/rails/enum_hash.rb +11 -10
- data/lib/rubocop/cop/rails/enum_uniqueness.rb +2 -1
- data/lib/rubocop/cop/rails/environment_comparison.rb +18 -14
- data/lib/rubocop/cop/rails/environment_variable_access.rb +67 -0
- data/lib/rubocop/cop/rails/exit.rb +4 -10
- data/lib/rubocop/cop/rails/file_path.rb +7 -8
- data/lib/rubocop/cop/rails/find_by.rb +13 -13
- data/lib/rubocop/cop/rails/find_by_id.rb +12 -21
- data/lib/rubocop/cop/rails/find_each.rb +19 -18
- data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +3 -2
- data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +37 -10
- data/lib/rubocop/cop/rails/helper_instance_variable.rb +30 -2
- data/lib/rubocop/cop/rails/http_positional_arguments.rb +32 -21
- data/lib/rubocop/cop/rails/http_status.rb +7 -9
- data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +8 -6
- data/lib/rubocop/cop/rails/index_by.rb +11 -2
- data/lib/rubocop/cop/rails/index_with.rb +11 -2
- data/lib/rubocop/cop/rails/inquiry.rb +7 -2
- data/lib/rubocop/cop/rails/inverse_of.rb +3 -2
- data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +17 -15
- data/lib/rubocop/cop/rails/link_to_blank.rb +25 -23
- data/lib/rubocop/cop/rails/mailer_name.rb +19 -13
- data/lib/rubocop/cop/rails/match_route.rb +14 -13
- data/lib/rubocop/cop/rails/negate_include.rb +10 -8
- data/lib/rubocop/cop/rails/not_null_column.rb +2 -1
- data/lib/rubocop/cop/rails/order_by_id.rb +52 -0
- data/lib/rubocop/cop/rails/output.rb +5 -2
- data/lib/rubocop/cop/rails/output_safety.rb +3 -2
- data/lib/rubocop/cop/rails/pick.rb +14 -12
- data/lib/rubocop/cop/rails/pluck.rb +6 -9
- data/lib/rubocop/cop/rails/pluck_id.rb +4 -6
- data/lib/rubocop/cop/rails/pluck_in_where.rb +39 -5
- data/lib/rubocop/cop/rails/pluralization_grammar.rb +10 -14
- data/lib/rubocop/cop/rails/presence.rb +12 -13
- data/lib/rubocop/cop/rails/present.rb +30 -24
- data/lib/rubocop/cop/rails/rake_environment.rb +8 -10
- data/lib/rubocop/cop/rails/read_write_attribute.rb +12 -11
- data/lib/rubocop/cop/rails/redundant_allow_nil.rb +29 -31
- data/lib/rubocop/cop/rails/redundant_foreign_key.rb +9 -12
- data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +11 -10
- data/lib/rubocop/cop/rails/reflection_class_name.rb +18 -4
- data/lib/rubocop/cop/rails/refute_methods.rb +9 -10
- data/lib/rubocop/cop/rails/relative_date_constant.rb +34 -22
- data/lib/rubocop/cop/rails/render_inline.rb +2 -1
- data/lib/rubocop/cop/rails/render_plain_text.rb +9 -14
- data/lib/rubocop/cop/rails/request_referer.rb +7 -7
- data/lib/rubocop/cop/rails/require_dependency.rb +38 -0
- data/lib/rubocop/cop/rails/reversible_migration.rb +83 -8
- data/lib/rubocop/cop/rails/reversible_migration_method_definition.rb +75 -0
- data/lib/rubocop/cop/rails/safe_navigation.rb +30 -11
- data/lib/rubocop/cop/rails/safe_navigation_with_blank.rb +5 -10
- data/lib/rubocop/cop/rails/save_bang.rb +19 -22
- data/lib/rubocop/cop/rails/scope_args.rb +2 -1
- data/lib/rubocop/cop/rails/short_i18n.rb +7 -9
- data/lib/rubocop/cop/rails/skips_model_validations.rb +4 -4
- data/lib/rubocop/cop/rails/squished_sql_heredocs.rb +82 -0
- data/lib/rubocop/cop/rails/time_zone.rb +35 -25
- data/lib/rubocop/cop/rails/time_zone_assignment.rb +37 -0
- data/lib/rubocop/cop/rails/uniq_before_pluck.rb +6 -6
- data/lib/rubocop/cop/rails/unique_validation_without_index.rb +18 -8
- data/lib/rubocop/cop/rails/unknown_env.rb +3 -3
- data/lib/rubocop/cop/rails/validation.rb +15 -14
- data/lib/rubocop/cop/rails/where_equals.rb +98 -0
- data/lib/rubocop/cop/rails/where_exists.rb +85 -16
- data/lib/rubocop/cop/rails/where_not.rb +101 -0
- data/lib/rubocop/cop/rails_cops.rb +12 -0
- data/lib/rubocop/rails.rb +2 -0
- data/lib/rubocop/rails/schema_loader.rb +4 -4
- data/lib/rubocop/rails/schema_loader/schema.rb +4 -8
- data/lib/rubocop/rails/version.rb +5 -1
- metadata +33 -14
@@ -13,11 +13,12 @@ module RuboCop
|
|
13
13
|
#
|
14
14
|
# # good
|
15
15
|
# User.find_by(name: 'Bruce')
|
16
|
-
class FindBy <
|
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
|
-
|
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(
|
33
|
-
|
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
|
-
|
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
|
-
|
48
|
-
|
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 <
|
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
|
-
|
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
|
-
|
52
|
+
register_offense(range, id_value, bad_method)
|
57
53
|
end
|
58
54
|
end
|
59
55
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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
|
-
|
69
|
-
|
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,39 @@ module RuboCop
|
|
12
12
|
#
|
13
13
|
# # good
|
14
14
|
# User.all.find_each
|
15
|
-
|
15
|
+
#
|
16
|
+
# @example IgnoredMethods: ['order']
|
17
|
+
# # good
|
18
|
+
# User.order(:foo).each
|
19
|
+
class FindEach < Base
|
20
|
+
include ActiveRecordHelper
|
21
|
+
extend AutoCorrector
|
22
|
+
|
16
23
|
MSG = 'Use `find_each` instead of `each`.'
|
24
|
+
RESTRICT_ON_SEND = %i[each].freeze
|
17
25
|
|
18
26
|
SCOPE_METHODS = %i[
|
19
27
|
all eager_load includes joins left_joins left_outer_joins not preload
|
20
28
|
references unscoped where
|
21
29
|
].freeze
|
22
|
-
IGNORED_METHODS = %i[order limit select].freeze
|
23
30
|
|
24
31
|
def on_send(node)
|
25
|
-
return unless node.receiver&.send_type?
|
26
|
-
node.method?(:each)
|
27
|
-
|
32
|
+
return unless node.receiver&.send_type?
|
28
33
|
return unless SCOPE_METHODS.include?(node.receiver.method_name)
|
29
|
-
return if
|
34
|
+
return if node.receiver.receiver.nil? && !inherit_active_record_base?(node)
|
35
|
+
return if ignored?(node)
|
30
36
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
->(corrector) { corrector.replace(node.loc.selector, 'find_each') }
|
37
|
+
range = node.loc.selector
|
38
|
+
add_offense(range) do |corrector|
|
39
|
+
corrector.replace(range, 'find_each')
|
40
|
+
end
|
36
41
|
end
|
37
42
|
|
38
43
|
private
|
39
44
|
|
40
|
-
def
|
41
|
-
node.each_node(:send).map(&:method_name)
|
42
|
-
|
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)
|
45
|
+
def ignored?(node)
|
46
|
+
method_chain = node.each_node(:send).map(&:method_name)
|
47
|
+
(cop_config['IgnoredMethods'].map(&:to_sym) & method_chain).any?
|
47
48
|
end
|
48
49
|
end
|
49
50
|
end
|
@@ -11,13 +11,14 @@ module RuboCop
|
|
11
11
|
#
|
12
12
|
# # good
|
13
13
|
# # has_many :ingredients, through: :recipe_ingredients
|
14
|
-
class HasAndBelongsToMany <
|
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
|
21
|
+
add_offense(node.loc.selector)
|
21
22
|
end
|
22
23
|
end
|
23
24
|
end
|
@@ -5,7 +5,9 @@ module RuboCop
|
|
5
5
|
module Rails
|
6
6
|
# This cop looks for `has_many` or `has_one` associations that don't
|
7
7
|
# specify a `:dependent` option.
|
8
|
-
#
|
8
|
+
#
|
9
|
+
# It doesn't register an offense if `:through` or `dependent: nil`
|
10
|
+
# is specified, or if the model is read-only.
|
9
11
|
#
|
10
12
|
# @example
|
11
13
|
# # bad
|
@@ -18,10 +20,21 @@ module RuboCop
|
|
18
20
|
# class User < ActiveRecord::Base
|
19
21
|
# has_many :comments, dependent: :restrict_with_exception
|
20
22
|
# has_one :avatar, dependent: :destroy
|
23
|
+
# has_many :articles, dependent: nil
|
21
24
|
# has_many :patients, through: :appointments
|
22
25
|
# end
|
23
|
-
|
26
|
+
#
|
27
|
+
# class User < ActiveRecord::Base
|
28
|
+
# has_many :comments
|
29
|
+
# has_one :avatar
|
30
|
+
#
|
31
|
+
# def readonly?
|
32
|
+
# true
|
33
|
+
# end
|
34
|
+
# end
|
35
|
+
class HasManyOrHasOneDependent < Base
|
24
36
|
MSG = 'Specify a `:dependent` option.'
|
37
|
+
RESTRICT_ON_SEND = %i[has_many has_one].freeze
|
25
38
|
|
26
39
|
def_node_search :active_resource_class?, <<~PATTERN
|
27
40
|
(const (const nil? :ActiveResource) :Base)
|
@@ -36,7 +49,7 @@ module RuboCop
|
|
36
49
|
PATTERN
|
37
50
|
|
38
51
|
def_node_matcher :dependent_option?, <<~PATTERN
|
39
|
-
(pair (sym :dependent) !nil)
|
52
|
+
(pair (sym :dependent) {!nil (nil)})
|
40
53
|
PATTERN
|
41
54
|
|
42
55
|
def_node_matcher :present_option?, <<~PATTERN
|
@@ -50,24 +63,38 @@ module RuboCop
|
|
50
63
|
(args) ...)
|
51
64
|
PATTERN
|
52
65
|
|
53
|
-
|
54
|
-
|
66
|
+
def_node_matcher :association_extension_block?, <<~PATTERN
|
67
|
+
(block
|
68
|
+
(send nil? :has_many _)
|
69
|
+
(args) ...)
|
70
|
+
PATTERN
|
55
71
|
|
56
|
-
|
57
|
-
|
58
|
-
|
72
|
+
def_node_matcher :readonly?, <<~PATTERN
|
73
|
+
(def :readonly?
|
74
|
+
(args)
|
75
|
+
(true))
|
76
|
+
PATTERN
|
59
77
|
|
78
|
+
def on_send(node)
|
79
|
+
return if active_resource?(node.parent) || readonly_model?(node)
|
80
|
+
return if !association_without_options?(node) && valid_options?(association_with_options?(node))
|
60
81
|
return if valid_options_in_with_options_block?(node)
|
61
82
|
|
62
|
-
add_offense(node
|
83
|
+
add_offense(node.loc.selector)
|
63
84
|
end
|
64
85
|
|
65
86
|
private
|
66
87
|
|
88
|
+
def readonly_model?(node)
|
89
|
+
return false unless (parent = node.parent)
|
90
|
+
|
91
|
+
parent.each_descendant(:def).any? { |def_node| readonly?(def_node) }
|
92
|
+
end
|
93
|
+
|
67
94
|
def valid_options_in_with_options_block?(node)
|
68
95
|
return true unless node.parent
|
69
96
|
|
70
|
-
n = node.parent.begin_type? ? node.parent.parent : node.parent
|
97
|
+
n = node.parent.begin_type? || association_extension_block?(node.parent) ? node.parent.parent : node.parent
|
71
98
|
|
72
99
|
contain_valid_options_in_with_options_block?(n)
|
73
100
|
end
|
@@ -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
|
-
|
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
|
-
|
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,10 @@ module RuboCop
|
|
16
16
|
#
|
17
17
|
# # good
|
18
18
|
# get :new, params: { user_id: 1 }
|
19
|
-
|
19
|
+
# get :new, **options
|
20
|
+
class HttpPositionalArguments < Base
|
21
|
+
include RangeHelp
|
22
|
+
extend AutoCorrector
|
20
23
|
extend TargetRailsVersion
|
21
24
|
|
22
25
|
MSG = 'Use keyword arguments instead of ' \
|
@@ -24,36 +27,37 @@ module RuboCop
|
|
24
27
|
KEYWORD_ARGS = %i[
|
25
28
|
method params session body flash xhr as headers env to
|
26
29
|
].freeze
|
27
|
-
|
30
|
+
RESTRICT_ON_SEND = %i[get post put patch delete head].freeze
|
28
31
|
|
29
32
|
minimum_target_rails_version 5.0
|
30
33
|
|
31
34
|
def_node_matcher :http_request?, <<~PATTERN
|
32
|
-
(send nil? {#{
|
35
|
+
(send nil? {#{RESTRICT_ON_SEND.map(&:inspect).join(' ')}} !nil? $_ ...)
|
36
|
+
PATTERN
|
37
|
+
|
38
|
+
def_node_matcher :kwsplat_hash?, <<~PATTERN
|
39
|
+
(hash (kwsplat _))
|
33
40
|
PATTERN
|
34
41
|
|
35
42
|
def on_send(node)
|
36
43
|
http_request?(node) do |data|
|
37
44
|
return unless needs_conversion?(data)
|
38
45
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
def autocorrect(node)
|
55
|
-
lambda do |corrector|
|
56
|
-
corrector.replace(node.loc.expression, correction(node))
|
46
|
+
message = format(MSG, verb: node.method_name)
|
47
|
+
|
48
|
+
add_offense(highlight_range(node), message: message) do |corrector|
|
49
|
+
# given a pre Rails 5 method: get :new, {user_id: @user.id}, {}
|
50
|
+
#
|
51
|
+
# @return lambda of auto correct procedure
|
52
|
+
# the result should look like:
|
53
|
+
# get :new, params: { user_id: @user.id }, session: {}
|
54
|
+
# the http_method is the method used to call the controller
|
55
|
+
# the controller node can be a symbol, method, object or string
|
56
|
+
# that represents the path/action on the Rails controller
|
57
|
+
# the data is the http parameters and environment sent in
|
58
|
+
# the Rails 5 http call
|
59
|
+
corrector.replace(node.loc.expression, correction(node))
|
60
|
+
end
|
57
61
|
end
|
58
62
|
end
|
59
63
|
|
@@ -61,6 +65,7 @@ module RuboCop
|
|
61
65
|
|
62
66
|
def needs_conversion?(data)
|
63
67
|
return true unless data.hash_type?
|
68
|
+
return false if kwsplat_hash?(data)
|
64
69
|
|
65
70
|
data.each_pair.none? do |pair|
|
66
71
|
special_keyword_arg?(pair.key) ||
|
@@ -76,6 +81,12 @@ module RuboCop
|
|
76
81
|
node.sym_type? && node.value == :format
|
77
82
|
end
|
78
83
|
|
84
|
+
def highlight_range(node)
|
85
|
+
_http_path, *data = *node.arguments
|
86
|
+
|
87
|
+
range_between(data.first.source_range.begin_pos, data.last.source_range.end_pos)
|
88
|
+
end
|
89
|
+
|
79
90
|
def convert_hash_data(data, type)
|
80
91
|
return '' if data.hash_type? && data.empty?
|
81
92
|
|
@@ -31,8 +31,11 @@ module RuboCop
|
|
31
31
|
# render plain: 'foo/bar', status: 304
|
32
32
|
# redirect_to root_url, status: 301
|
33
33
|
#
|
34
|
-
class HttpStatus <
|
34
|
+
class HttpStatus < Base
|
35
35
|
include ConfigurableEnforcedStyle
|
36
|
+
extend AutoCorrector
|
37
|
+
|
38
|
+
RESTRICT_ON_SEND = %i[render redirect_to].freeze
|
36
39
|
|
37
40
|
def_node_matcher :http_status, <<~PATTERN
|
38
41
|
{
|
@@ -53,14 +56,9 @@ module RuboCop
|
|
53
56
|
checker = checker_class.new(status)
|
54
57
|
return unless checker.offensive?
|
55
58
|
|
56
|
-
add_offense(checker.node, message: checker.message)
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
def autocorrect(node)
|
61
|
-
lambda do |corrector|
|
62
|
-
checker = checker_class.new(node)
|
63
|
-
corrector.replace(node.loc.expression, checker.preferred_style)
|
59
|
+
add_offense(checker.node, message: checker.message) do |corrector|
|
60
|
+
corrector.replace(checker.node.loc.expression, checker.preferred_style)
|
61
|
+
end
|
64
62
|
end
|
65
63
|
end
|
66
64
|
|