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
@@ -23,8 +23,11 @@ module RuboCop
|
|
23
23
|
# # good
|
24
24
|
# x = self[:attr]
|
25
25
|
# self[:attr] = val
|
26
|
-
class ReadWriteAttribute <
|
26
|
+
class ReadWriteAttribute < Base
|
27
|
+
extend AutoCorrector
|
28
|
+
|
27
29
|
MSG = 'Prefer `%<prefer>s` over `%<current>s`.'
|
30
|
+
RESTRICT_ON_SEND = %i[read_attribute write_attribute].freeze
|
28
31
|
|
29
32
|
def_node_matcher :read_write_attribute?, <<~PATTERN
|
30
33
|
{
|
@@ -36,18 +39,16 @@ module RuboCop
|
|
36
39
|
def on_send(node)
|
37
40
|
return unless read_write_attribute?(node)
|
38
41
|
|
39
|
-
add_offense(node,
|
40
|
-
|
42
|
+
add_offense(node.loc.selector, message: message(node)) do |corrector|
|
43
|
+
case node.method_name
|
44
|
+
when :read_attribute
|
45
|
+
replacement = read_attribute_replacement(node)
|
46
|
+
when :write_attribute
|
47
|
+
replacement = write_attribute_replacement(node)
|
48
|
+
end
|
41
49
|
|
42
|
-
|
43
|
-
case node.method_name
|
44
|
-
when :read_attribute
|
45
|
-
replacement = read_attribute_replacement(node)
|
46
|
-
when :write_attribute
|
47
|
-
replacement = write_attribute_replacement(node)
|
50
|
+
corrector.replace(node.source_range, replacement)
|
48
51
|
end
|
49
|
-
|
50
|
-
->(corrector) { corrector.replace(node.source_range, replacement) }
|
51
52
|
end
|
52
53
|
|
53
54
|
private
|
@@ -26,8 +26,9 @@ module RuboCop
|
|
26
26
|
# # Here, `nil` is valid but `''` is not
|
27
27
|
# validates :x, length: { is: 5 }, allow_nil: true, allow_blank: false
|
28
28
|
#
|
29
|
-
class RedundantAllowNil <
|
29
|
+
class RedundantAllowNil < Base
|
30
30
|
include RangeHelp
|
31
|
+
extend AutoCorrector
|
31
32
|
|
32
33
|
MSG_SAME =
|
33
34
|
'`allow_nil` is redundant when `allow_blank` has the same value.'
|
@@ -35,59 +36,56 @@ module RuboCop
|
|
35
36
|
MSG_ALLOW_NIL_FALSE =
|
36
37
|
'`allow_nil: false` is redundant when `allow_blank` is true.'
|
37
38
|
|
38
|
-
|
39
|
-
return unless node.method?(:validates)
|
39
|
+
RESTRICT_ON_SEND = %i[validates].freeze
|
40
40
|
|
41
|
+
def on_send(node)
|
41
42
|
allow_nil, allow_blank = find_allow_nil_and_allow_blank(node)
|
42
43
|
return unless allow_nil && allow_blank
|
43
44
|
|
44
45
|
allow_nil_val = allow_nil.children.last
|
45
46
|
allow_blank_val = allow_blank.children.last
|
46
47
|
|
47
|
-
|
48
|
+
if allow_nil_val.type == allow_blank_val.type
|
49
|
+
register_offense(allow_nil, MSG_SAME)
|
50
|
+
elsif allow_nil_val.false_type? && allow_blank_val.true_type?
|
51
|
+
register_offense(allow_nil, MSG_ALLOW_NIL_FALSE)
|
52
|
+
end
|
48
53
|
end
|
49
54
|
|
50
|
-
|
51
|
-
|
52
|
-
|
55
|
+
private
|
56
|
+
|
57
|
+
def register_offense(allow_nil, message)
|
58
|
+
add_offense(allow_nil, message: message) do |corrector|
|
59
|
+
prv_sib = previous_sibling(allow_nil)
|
60
|
+
nxt_sib = next_sibling(allow_nil)
|
53
61
|
|
54
|
-
lambda do |corrector|
|
55
62
|
if nxt_sib
|
56
|
-
corrector.remove(range_between(node_beg(
|
63
|
+
corrector.remove(range_between(node_beg(allow_nil), node_beg(nxt_sib)))
|
57
64
|
elsif prv_sib
|
58
|
-
corrector.remove(range_between(node_end(prv_sib), node_end(
|
65
|
+
corrector.remove(range_between(node_end(prv_sib), node_end(allow_nil)))
|
59
66
|
else
|
60
|
-
corrector.remove(
|
67
|
+
corrector.remove(allow_nil.loc.expression)
|
61
68
|
end
|
62
69
|
end
|
63
70
|
end
|
64
71
|
|
65
|
-
private
|
66
|
-
|
67
|
-
def offense(allow_nil_val, allow_blank_val, allow_nil)
|
68
|
-
if allow_nil_val.type == allow_blank_val.type
|
69
|
-
add_offense(allow_nil, message: MSG_SAME)
|
70
|
-
elsif allow_nil_val.false_type? && allow_blank_val.true_type?
|
71
|
-
add_offense(allow_nil, message: MSG_ALLOW_NIL_FALSE)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
72
|
def find_allow_nil_and_allow_blank(node)
|
76
|
-
allow_nil = nil
|
77
|
-
allow_blank = nil
|
73
|
+
allow_nil, allow_blank = nil
|
78
74
|
|
79
|
-
node.
|
80
|
-
|
75
|
+
node.each_child_node do |child_node|
|
76
|
+
if child_node.pair_type?
|
77
|
+
key = child_node.children.first.source
|
81
78
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
79
|
+
allow_nil = child_node if key == 'allow_nil'
|
80
|
+
allow_blank = child_node if key == 'allow_blank'
|
81
|
+
end
|
82
|
+
return [allow_nil, allow_blank] if allow_nil && allow_blank
|
86
83
|
|
87
|
-
|
84
|
+
found_in_children_nodes = find_allow_nil_and_allow_blank(child_node)
|
85
|
+
return found_in_children_nodes if found_in_children_nodes
|
88
86
|
end
|
89
87
|
|
90
|
-
|
88
|
+
nil
|
91
89
|
end
|
92
90
|
|
93
91
|
def previous_sibling(node)
|
@@ -24,10 +24,12 @@ module RuboCop
|
|
24
24
|
# class Comment
|
25
25
|
# belongs_to :author, foreign_key: 'user_id'
|
26
26
|
# end
|
27
|
-
class RedundantForeignKey <
|
27
|
+
class RedundantForeignKey < Base
|
28
28
|
include RangeHelp
|
29
|
+
extend AutoCorrector
|
29
30
|
|
30
31
|
MSG = 'Specifying the default value for `foreign_key` is redundant.'
|
32
|
+
RESTRICT_ON_SEND = %i[belongs_to has_one has_many has_and_belongs_to_many].freeze
|
31
33
|
|
32
34
|
def_node_matcher :association_with_foreign_key, <<~PATTERN
|
33
35
|
(send nil? ${:belongs_to :has_one :has_many :has_and_belongs_to_many} ({sym str} $_)
|
@@ -38,18 +40,13 @@ module RuboCop
|
|
38
40
|
def on_send(node)
|
39
41
|
association_with_foreign_key(node) do |type, name, options, foreign_key_pair, foreign_key|
|
40
42
|
if redundant?(node, type, name, options, foreign_key)
|
41
|
-
add_offense(
|
42
|
-
|
43
|
-
|
44
|
-
end
|
43
|
+
add_offense(foreign_key_pair.loc.expression) do |corrector|
|
44
|
+
range = range_with_surrounding_space(range: foreign_key_pair.source_range, side: :left)
|
45
|
+
range = range_with_surrounding_comma(range, :left)
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
range = range_with_surrounding_comma(range, :left)
|
50
|
-
|
51
|
-
lambda do |corrector|
|
52
|
-
corrector.remove(range)
|
47
|
+
corrector.remove(range)
|
48
|
+
end
|
49
|
+
end
|
53
50
|
end
|
54
51
|
end
|
55
52
|
|
@@ -54,8 +54,9 @@ module RuboCop
|
|
54
54
|
# merger.invoke(another_receiver)
|
55
55
|
# end
|
56
56
|
# end
|
57
|
-
class RedundantReceiverInWithOptions <
|
57
|
+
class RedundantReceiverInWithOptions < Base
|
58
58
|
include RangeHelp
|
59
|
+
extend AutoCorrector
|
59
60
|
|
60
61
|
MSG = 'Redundant receiver in `with_options`.'
|
61
62
|
|
@@ -86,22 +87,22 @@ module RuboCop
|
|
86
87
|
if send_nodes.all? { |n| same_value?(arg, n.receiver) }
|
87
88
|
send_nodes.each do |send_node|
|
88
89
|
receiver = send_node.receiver
|
89
|
-
add_offense(
|
90
|
+
add_offense(receiver.source_range) do |corrector|
|
91
|
+
autocorrect(corrector, send_node)
|
92
|
+
end
|
90
93
|
end
|
91
94
|
end
|
92
95
|
end
|
93
96
|
end
|
94
97
|
|
95
|
-
def autocorrect(node)
|
96
|
-
lambda do |corrector|
|
97
|
-
corrector.remove(node.receiver.source_range)
|
98
|
-
corrector.remove(node.loc.dot)
|
99
|
-
corrector.remove(block_argument_range(node))
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
98
|
private
|
104
99
|
|
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))
|
104
|
+
end
|
105
|
+
|
105
106
|
def block_argument_range(node)
|
106
107
|
block_node = node.each_ancestor(:block).first
|
107
108
|
block_argument = block_node.children[1].source_range
|
@@ -5,6 +5,8 @@ module RuboCop
|
|
5
5
|
module Rails
|
6
6
|
# This cop checks if the value of the option `class_name`, in
|
7
7
|
# the definition of a reflection is a string.
|
8
|
+
# It is marked as unsafe because it cannot be determined whether
|
9
|
+
# constant or method return value specified to `class_name` is a string.
|
8
10
|
#
|
9
11
|
# @example
|
10
12
|
# # bad
|
@@ -13,22 +15,34 @@ module RuboCop
|
|
13
15
|
#
|
14
16
|
# # good
|
15
17
|
# has_many :accounts, class_name: 'Account'
|
16
|
-
class ReflectionClassName <
|
18
|
+
class ReflectionClassName < Base
|
17
19
|
MSG = 'Use a string value for `class_name`.'
|
20
|
+
RESTRICT_ON_SEND = %i[has_many has_one belongs_to].freeze
|
21
|
+
ALLOWED_REFLECTION_CLASS_TYPES = %i[dstr str sym].freeze
|
18
22
|
|
19
23
|
def_node_matcher :association_with_reflection, <<~PATTERN
|
20
|
-
(send nil? {:has_many :has_one :belongs_to} _
|
24
|
+
(send nil? {:has_many :has_one :belongs_to} _ _ ?
|
21
25
|
(hash <$#reflection_class_name ...>)
|
22
26
|
)
|
23
27
|
PATTERN
|
24
28
|
|
25
29
|
def_node_matcher :reflection_class_name, <<~PATTERN
|
26
|
-
(pair (sym :class_name)
|
30
|
+
(pair (sym :class_name) #reflection_class_value?)
|
27
31
|
PATTERN
|
28
32
|
|
29
33
|
def on_send(node)
|
30
34
|
association_with_reflection(node) do |reflection_class_name|
|
31
|
-
add_offense(
|
35
|
+
add_offense(reflection_class_name.loc.expression)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def reflection_class_value?(class_value)
|
42
|
+
if class_value.send_type?
|
43
|
+
!class_value.method?(:to_s) || class_value.receiver.const_type?
|
44
|
+
else
|
45
|
+
!ALLOWED_REFLECTION_CLASS_TYPES.include?(class_value.type)
|
32
46
|
end
|
33
47
|
end
|
34
48
|
end
|
@@ -28,8 +28,9 @@ module RuboCop
|
|
28
28
|
# refute_empty [1, 2, 3]
|
29
29
|
# refute_equal true, false
|
30
30
|
#
|
31
|
-
class RefuteMethods <
|
31
|
+
class RefuteMethods < Base
|
32
32
|
include ConfigurableEnforcedStyle
|
33
|
+
extend AutoCorrector
|
33
34
|
|
34
35
|
MSG = 'Prefer `%<good_method>s` over `%<bad_method>s`.'
|
35
36
|
|
@@ -53,21 +54,19 @@ module RuboCop
|
|
53
54
|
REFUTE_METHODS = CORRECTIONS.keys.freeze
|
54
55
|
ASSERT_NOT_METHODS = CORRECTIONS.values.freeze
|
55
56
|
|
57
|
+
RESTRICT_ON_SEND = REFUTE_METHODS + ASSERT_NOT_METHODS
|
58
|
+
|
56
59
|
def_node_matcher :offensive?, '(send nil? #bad_method? ...)'
|
57
60
|
|
58
61
|
def on_send(node)
|
59
62
|
return unless offensive?(node)
|
60
63
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
def autocorrect(node)
|
66
|
-
bad_method = node.method_name
|
67
|
-
good_method = convert_good_method(bad_method)
|
64
|
+
method_name = node.method_name
|
65
|
+
message = offense_message(method_name)
|
66
|
+
range = node.loc.selector
|
68
67
|
|
69
|
-
|
70
|
-
corrector.replace(
|
68
|
+
add_offense(range, message: message) do |corrector|
|
69
|
+
corrector.replace(range, convert_good_method(method_name))
|
71
70
|
end
|
72
71
|
end
|
73
72
|
|
@@ -27,15 +27,23 @@ module RuboCop
|
|
27
27
|
# 1.week.since
|
28
28
|
# end
|
29
29
|
# end
|
30
|
-
class RelativeDateConstant <
|
30
|
+
class RelativeDateConstant < Base
|
31
31
|
include RangeHelp
|
32
|
+
extend AutoCorrector
|
32
33
|
|
33
|
-
MSG = 'Do not assign
|
34
|
+
MSG = 'Do not assign `%<method_name>s` to constants as it ' \
|
34
35
|
'will be evaluated only once.'
|
36
|
+
RELATIVE_DATE_METHODS = %i[since from_now after ago until before yesterday tomorrow].freeze
|
35
37
|
|
36
38
|
def on_casgn(node)
|
37
|
-
|
38
|
-
|
39
|
+
return if node.children[2]&.block_type?
|
40
|
+
|
41
|
+
node.each_descendant(:send) do |send_node|
|
42
|
+
relative_date?(send_node) do |method_name|
|
43
|
+
add_offense(node, message: message(method_name)) do |corrector|
|
44
|
+
autocorrect(corrector, node)
|
45
|
+
end
|
46
|
+
end
|
39
47
|
end
|
40
48
|
end
|
41
49
|
|
@@ -48,10 +56,9 @@ module RuboCop
|
|
48
56
|
next unless name.casgn_type?
|
49
57
|
|
50
58
|
relative_date?(value) do |method_name|
|
51
|
-
add_offense(
|
52
|
-
|
53
|
-
|
54
|
-
message: format(MSG, method_name: method_name))
|
59
|
+
add_offense(offense_range(name, value), message: message(method_name)) do |corrector|
|
60
|
+
autocorrect(corrector, node)
|
61
|
+
end
|
55
62
|
end
|
56
63
|
end
|
57
64
|
end
|
@@ -62,7 +69,9 @@ module RuboCop
|
|
62
69
|
end
|
63
70
|
end
|
64
71
|
|
65
|
-
|
72
|
+
private
|
73
|
+
|
74
|
+
def autocorrect(corrector, node)
|
66
75
|
return unless node.casgn_type?
|
67
76
|
|
68
77
|
scope, const_name, value = *node
|
@@ -72,28 +81,31 @@ module RuboCop
|
|
72
81
|
new_code = ["def self.#{const_name.downcase}",
|
73
82
|
"#{indent}#{value.source}",
|
74
83
|
'end'].join("\n#{indent}")
|
75
|
-
|
84
|
+
|
85
|
+
corrector.replace(node.source_range, new_code)
|
76
86
|
end
|
77
87
|
|
78
|
-
|
88
|
+
def message(method_name)
|
89
|
+
format(MSG, method_name: method_name)
|
90
|
+
end
|
79
91
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
92
|
+
def offense_range(name, value)
|
93
|
+
range_between(name.loc.expression.begin_pos, value.loc.expression.end_pos)
|
94
|
+
end
|
95
|
+
|
96
|
+
def relative_date_method?(method_name)
|
97
|
+
RELATIVE_DATE_METHODS.include?(method_name)
|
98
|
+
end
|
87
99
|
|
88
100
|
def_node_matcher :relative_date_or_assignment?, <<~PATTERN
|
89
|
-
(:or_asgn (casgn _ _) (send _
|
101
|
+
(:or_asgn (casgn _ _) (send _ $#relative_date_method?))
|
90
102
|
PATTERN
|
91
103
|
|
92
104
|
def_node_matcher :relative_date?, <<~PATTERN
|
93
105
|
{
|
94
|
-
({erange irange} _ (send _
|
95
|
-
({erange irange} (send _
|
96
|
-
(send _
|
106
|
+
({erange irange} _ (send _ $#relative_date_method?))
|
107
|
+
({erange irange} (send _ $#relative_date_method?) _)
|
108
|
+
(send _ $#relative_date_method?)
|
97
109
|
}
|
98
110
|
PATTERN
|
99
111
|
end
|
@@ -24,8 +24,9 @@ module RuboCop
|
|
24
24
|
# end
|
25
25
|
# end
|
26
26
|
#
|
27
|
-
class RenderInline <
|
27
|
+
class RenderInline < Base
|
28
28
|
MSG = 'Prefer using a template over inline rendering.'
|
29
|
+
RESTRICT_ON_SEND = %i[render].freeze
|
29
30
|
|
30
31
|
def_node_matcher :render_with_inline_option?, <<~PATTERN
|
31
32
|
(send nil? :render (hash <(pair {(sym :inline) (str "inline")} _) ...>))
|
@@ -24,30 +24,25 @@ module RuboCop
|
|
24
24
|
# # bad - sets MIME type to `text/html`
|
25
25
|
# render text: 'Ruby!'
|
26
26
|
#
|
27
|
-
class RenderPlainText <
|
27
|
+
class RenderPlainText < Base
|
28
|
+
extend AutoCorrector
|
29
|
+
|
28
30
|
MSG = 'Prefer `render plain:` over `render text:`.'
|
31
|
+
RESTRICT_ON_SEND = %i[render].freeze
|
29
32
|
|
30
33
|
def_node_matcher :render_plain_text?, <<~PATTERN
|
31
34
|
(send nil? :render $(hash <$(pair (sym :text) $_) ...>))
|
32
35
|
PATTERN
|
33
36
|
|
34
37
|
def on_send(node)
|
35
|
-
render_plain_text?(node) do |options_node, _option_node, _option_value|
|
36
|
-
content_type_node = find_content_type(options_node)
|
37
|
-
add_offense(node) if compatible_content_type?(content_type_node)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def autocorrect(node)
|
42
38
|
render_plain_text?(node) do |options_node, option_node, option_value|
|
43
39
|
content_type_node = find_content_type(options_node)
|
44
|
-
|
40
|
+
return unless compatible_content_type?(content_type_node)
|
41
|
+
|
42
|
+
add_offense(node) do |corrector|
|
43
|
+
rest_options = options_node.pairs - [option_node, content_type_node].compact
|
45
44
|
|
46
|
-
|
47
|
-
corrector.replace(
|
48
|
-
node,
|
49
|
-
replacement(rest_options, option_value)
|
50
|
-
)
|
45
|
+
corrector.replace(node, replacement(rest_options, option_value))
|
51
46
|
end
|
52
47
|
end
|
53
48
|
end
|