rubocop-rails 2.32.0 → 2.34.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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/config/default.yml +47 -3
  3. data/lib/rubocop/cop/mixin/active_record_helper.rb +1 -1
  4. data/lib/rubocop/cop/mixin/index_method.rb +4 -0
  5. data/lib/rubocop/cop/rails/action_controller_flash_before_render.rb +4 -2
  6. data/lib/rubocop/cop/rails/delegate.rb +4 -4
  7. data/lib/rubocop/cop/rails/duplicate_association.rb +1 -1
  8. data/lib/rubocop/cop/rails/duplicate_scope.rb +2 -2
  9. data/lib/rubocop/cop/rails/env.rb +57 -0
  10. data/lib/rubocop/cop/rails/env_local.rb +50 -26
  11. data/lib/rubocop/cop/rails/environment_comparison.rb +56 -48
  12. data/lib/rubocop/cop/rails/exit.rb +7 -4
  13. data/lib/rubocop/cop/rails/file_path.rb +2 -2
  14. data/lib/rubocop/cop/rails/find_by.rb +1 -1
  15. data/lib/rubocop/cop/rails/find_by_or_assignment_memoization.rb +124 -0
  16. data/lib/rubocop/cop/rails/helper_instance_variable.rb +16 -17
  17. data/lib/rubocop/cop/rails/http_status_name_consistency.rb +80 -0
  18. data/lib/rubocop/cop/rails/index_with.rb +5 -0
  19. data/lib/rubocop/cop/rails/inverse_of.rb +7 -0
  20. data/lib/rubocop/cop/rails/order_arguments.rb +84 -0
  21. data/lib/rubocop/cop/rails/output.rb +3 -0
  22. data/lib/rubocop/cop/rails/output_safety.rb +3 -1
  23. data/lib/rubocop/cop/rails/pluck.rb +6 -3
  24. data/lib/rubocop/cop/rails/presence.rb +52 -18
  25. data/lib/rubocop/cop/rails/read_write_attribute.rb +1 -1
  26. data/lib/rubocop/cop/rails/redirect_back_or_to.rb +89 -0
  27. data/lib/rubocop/cop/rails/redundant_presence_validation_on_belongs_to.rb +3 -3
  28. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +1 -1
  29. data/lib/rubocop/cop/rails/save_bang.rb +2 -2
  30. data/lib/rubocop/cop/rails/transaction_exit_statement.rb +4 -1
  31. data/lib/rubocop/cop/rails/where_exists.rb +5 -5
  32. data/lib/rubocop/cop/rails_cops.rb +5 -0
  33. data/lib/rubocop/rails/version.rb +1 -1
  34. metadata +9 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '009a04a87f7692e278ce16b061ff93814ada6644691ce2fdd4ac4c7659e68c4d'
4
- data.tar.gz: 313e26b30279cf9ebba24f5f99bc78b2b44433b24bc3522a6d4261de1cf72282
3
+ metadata.gz: ffddf417706a66433be596f397b807c824a2593bea0a5175907be9d9be318970
4
+ data.tar.gz: 40672bac8ab7a1961102c3f5306526fa98a360987c7095128313dd5bae7c5641
5
5
  SHA512:
6
- metadata.gz: 1f7397609be46c75da8ff050ed1325db850c39df7d097d9faeb6984162b706ed92e203f151a30a68aa41b3af8fcdd63b7e76c51ebdcfe31980129a853d7cd8a3
7
- data.tar.gz: 46006ebeb148838e1ae7f3dc56614b261fc90779c5e3772e163c9431034a89dbc614ef1cb1b913d5236fbc2b04708643fc27b593d8c0c4147898271c045cb4c7
6
+ metadata.gz: 16ba2fc1926397b8b5c413c207a9f45e80a30b53e1e73b215e18abf38218e3aea3ecd2090cc4858adfe4a9d32ebb527b83db57acb38cff48510d4eaf18dcdd9c
7
+ data.tar.gz: 6541216ccafd3cd5287517989ea8a49dcb4b547ca98d0c363f58ac5a11ebbe6452329ea0964357e7f9777a5224d05d271b6bd21ee31f0d0bffcb37dfaa26dbd0
data/config/default.yml CHANGED
@@ -91,6 +91,12 @@ Lint/UselessAccessModifier:
91
91
  - concern
92
92
  - concerning
93
93
 
94
+ Lint/UselessMethodDefinition:
95
+ # Avoids conflict with `Rails/LexicallyScopedActionFilter` cop.
96
+ Exclude:
97
+ - '**/app/controllers/**/*.rb'
98
+ - '**/app/mailers/**/*.rb'
99
+
94
100
  Rails:
95
101
  Enabled: true
96
102
  DocumentationBaseURL: https://docs.rubocop.org/rubocop-rails
@@ -402,7 +408,7 @@ Rails/DuplicateAssociation:
402
408
  VersionChanged: '2.18'
403
409
 
404
410
  Rails/DuplicateScope:
405
- Description: 'Multiple scopes share this same where clause.'
411
+ Description: 'Multiple scopes share this same expression.'
406
412
  Enabled: pending
407
413
  Severity: warning
408
414
  VersionAdded: '2.14'
@@ -453,6 +459,7 @@ Rails/EnumSyntax:
453
459
  VersionAdded: '2.26'
454
460
  Include:
455
461
  - '**/app/models/**/*.rb'
462
+ - '**/lib/**/*.rb'
456
463
 
457
464
  Rails/EnumUniqueness:
458
465
  Description: 'Avoid duplicate integers in hash-syntax `enum` declaration.'
@@ -461,6 +468,11 @@ Rails/EnumUniqueness:
461
468
  Include:
462
469
  - '**/app/models/**/*.rb'
463
470
 
471
+ Rails/Env:
472
+ Description: 'Use Feature Flags or config instead of `Rails.env`.'
473
+ Enabled: false
474
+ VersionAdded: '2.34'
475
+
464
476
  Rails/EnvLocal:
465
477
  Description: 'Use `Rails.env.local?` instead of `Rails.env.development? || Rails.env.test?`.'
466
478
  Enabled: pending
@@ -532,6 +544,13 @@ Rails/FindById:
532
544
  Enabled: 'pending'
533
545
  VersionAdded: '2.7'
534
546
 
547
+ Rails/FindByOrAssignmentMemoization:
548
+ Description: 'Avoid memoizing `find_by` results with `||=`.'
549
+ StyleGuide: 'https://rails.rubystyle.guide/#find-by-memoization'
550
+ Enabled: pending
551
+ Safe: false
552
+ VersionAdded: '2.33'
553
+
535
554
  Rails/FindEach:
536
555
  Description: 'Prefer all.find_each over all.each.'
537
556
  StyleGuide: 'https://rails.rubystyle.guide#find-each'
@@ -595,6 +614,14 @@ Rails/HttpStatus:
595
614
  - numeric
596
615
  - symbolic
597
616
 
617
+ Rails/HttpStatusNameConsistency:
618
+ Description: 'Enforces consistency by using the current HTTP status names.'
619
+ Enabled: pending
620
+ Severity: warning
621
+ VersionAdded: '2.34'
622
+ Include:
623
+ - '**/app/controllers/**/*.rb'
624
+
598
625
  Rails/I18nLazyLookup:
599
626
  Description: 'Checks for places where I18n "lazy" lookup can be used.'
600
627
  StyleGuide: 'https://rails.rubystyle.guide/#lazy-lookup'
@@ -647,8 +674,9 @@ Rails/IndexBy:
647
674
  Rails/IndexWith:
648
675
  Description: 'Prefer `index_with` over `each_with_object`, `to_h`, or `map`.'
649
676
  Enabled: true
677
+ SafeAutoCorrect: false
650
678
  VersionAdded: '2.5'
651
- VersionChanged: '2.8'
679
+ VersionChanged: '2.33'
652
680
 
653
681
  Rails/Inquiry:
654
682
  Description: "Prefer Ruby's comparison operators over Active Support's `Array#inquiry` and `String#inquiry`."
@@ -742,6 +770,13 @@ Rails/NotNullColumn:
742
770
  Include:
743
771
  - db/**/*.rb
744
772
 
773
+ Rails/OrderArguments:
774
+ Description: 'Prefer symbol arguments over strings in `order` method.'
775
+ StyleGuide: 'https://rails.rubystyle.guide/#order-arguments'
776
+ Enabled: pending
777
+ VersionAdded: '2.33'
778
+ Safe: false
779
+
745
780
  Rails/OrderById:
746
781
  Description: >-
747
782
  Do not use the `id` column for ordering.
@@ -809,6 +844,7 @@ Rails/Presence:
809
844
  Description: 'Checks code that can be written more easily using `Object#presence` defined by Active Support.'
810
845
  Enabled: true
811
846
  VersionAdded: '0.52'
847
+ VersionChanged: '2.34'
812
848
 
813
849
  Rails/Present:
814
850
  Description: 'Enforces use of `present?`.'
@@ -845,6 +881,14 @@ Rails/ReadWriteAttribute:
845
881
  Include:
846
882
  - '**/app/models/**/*.rb'
847
883
 
884
+ Rails/RedirectBackOrTo:
885
+ Description: >-
886
+ Use `redirect_back_or_to` instead of `redirect_back` with
887
+ `fallback_location` option.
888
+ Enabled: pending
889
+ Severity: warning
890
+ VersionAdded: '2.34'
891
+
848
892
  Rails/RedundantActiveRecordAllMethod:
849
893
  Description: Detect redundant `all` used as a receiver for Active Record query methods.
850
894
  StyleGuide: 'https://rails.rubystyle.guide/#redundant-all'
@@ -1126,7 +1170,7 @@ Rails/ThreeStateBooleanColumn:
1126
1170
  Rails/TimeZone:
1127
1171
  Description: 'Checks the correct usage of time zone aware methods.'
1128
1172
  StyleGuide: 'https://rails.rubystyle.guide#time'
1129
- Reference: 'http://danilenko.org/2012/7/6/rails_timezones'
1173
+ Reference: 'https://danilenko.org/2012/7/6/rails_timezones'
1130
1174
  Enabled: true
1131
1175
  SafeAutoCorrect: false
1132
1176
  VersionAdded: '0.30'
@@ -106,7 +106,7 @@ module RuboCop
106
106
  send_node = node.each_ancestor(:call).first
107
107
  return false unless send_node
108
108
 
109
- return true if WHERE_METHODS.include?(send_node.method_name)
109
+ return true if WHERE_METHODS.include?(send_node.method_name) && send_node.receiver != node
110
110
 
111
111
  receiver = send_node.receiver
112
112
  return false unless receiver&.send_type?
@@ -132,9 +132,13 @@ module RuboCop
132
132
  add_offense(
133
133
  node, message: "Prefer `#{new_method_name}` over `#{match_desc}`."
134
134
  ) do |corrector|
135
+ next if part_of_ignored_node?(node)
136
+
135
137
  correction = prepare_correction(node)
136
138
  execute_correction(corrector, node, correction)
137
139
  end
140
+
141
+ ignore_node(node)
138
142
  end
139
143
 
140
144
  def extract_captures(match)
@@ -73,7 +73,7 @@ module RuboCop
73
73
  return false if use_redirect_to?(context)
74
74
 
75
75
  context = node
76
- elsif context.right_siblings.empty?
76
+ elsif context.right_siblings.empty? && !use_redirect_to?(context.parent)
77
77
  return true
78
78
  end
79
79
  context = context.right_siblings
@@ -98,7 +98,9 @@ module RuboCop
98
98
  end
99
99
 
100
100
  def use_redirect_to?(context)
101
- context.right_siblings.compact.any? do |sibling|
101
+ context.right_siblings.any? do |sibling|
102
+ next unless sibling.is_a?(AST::Node)
103
+
102
104
  # Unwrap `return redirect_to :index`
103
105
  sibling = sibling.children.first if sibling.return_type? && sibling.children.one?
104
106
  sibling.send_type? && sibling.method?(:redirect_to)
@@ -76,7 +76,7 @@ module RuboCop
76
76
 
77
77
  def on_def(node)
78
78
  return unless trivial_delegate?(node)
79
- return if private_or_protected_delegation(node)
79
+ return if private_or_protected_delegation?(node)
80
80
  return if module_function_declared?(node)
81
81
 
82
82
  register_offense(node)
@@ -163,8 +163,8 @@ module RuboCop
163
163
  end
164
164
  end
165
165
 
166
- def private_or_protected_delegation(node)
167
- private_or_protected_inline(node) || node_visibility(node) != :public
166
+ def private_or_protected_delegation?(node)
167
+ private_or_protected_inline?(node) || node_visibility(node) != :public
168
168
  end
169
169
 
170
170
  def module_function_declared?(node)
@@ -173,7 +173,7 @@ module RuboCop
173
173
  end
174
174
  end
175
175
 
176
- def private_or_protected_inline(node)
176
+ def private_or_protected_inline?(node)
177
177
  processed_source[node.first_line - 1].strip.match?(/\A(private )|(protected )/)
178
178
  end
179
179
  end
@@ -94,7 +94,7 @@ module RuboCop
94
94
  filtered_nodes = association_nodes.reject { |node| node.method?(:belongs_to) }
95
95
  grouped_associations = filtered_nodes.group_by do |node|
96
96
  arguments = association(node).last
97
- next unless arguments.count == 1
97
+ next unless arguments.one?
98
98
 
99
99
  if (class_name = class_name(arguments.first))
100
100
  class_name.source
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Rails
6
- # Checks for multiple scopes in a model that have the same `where` clause. This
6
+ # Checks for multiple scopes in a model that have the same expression. This
7
7
  # often means you copy/pasted a scope, updated the name, and forgot to change the condition.
8
8
  #
9
9
  # @example
@@ -19,7 +19,7 @@ module RuboCop
19
19
  class DuplicateScope < Base
20
20
  include ClassSendNodeHelper
21
21
 
22
- MSG = 'Multiple scopes share this same where clause.'
22
+ MSG = 'Multiple scopes share this same expression.'
23
23
 
24
24
  def_node_matcher :scope, <<~PATTERN
25
25
  (send nil? :scope _ $...)
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Rails
6
+ # Checks for usage of `Rails.env` which can be replaced with Feature Flags
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ # Rails.env.production? || Rails.env.local?
12
+ #
13
+ # # good
14
+ # if FeatureFlag.enabled?(:new_feature)
15
+ # # new feature code
16
+ # end
17
+ #
18
+ class Env < Base
19
+ MSG = 'Use Feature Flags or config instead of `Rails.env`.'
20
+ RESTRICT_ON_SEND = %i[env].freeze
21
+ # This allow list is derived from:
22
+ # (Rails.env.methods - Object.instance_methods).select { |m| m.to_s.end_with?('?') }
23
+ # and then removing the environment specific methods like development?, test?, production?, local?
24
+ ALLOWED_LIST = Set.new(
25
+ %i[
26
+ unicode_normalized?
27
+ exclude?
28
+ empty?
29
+ acts_like_string?
30
+ include?
31
+ is_utf8?
32
+ casecmp?
33
+ match?
34
+ starts_with?
35
+ ends_with?
36
+ start_with?
37
+ end_with?
38
+ valid_encoding?
39
+ ascii_only?
40
+ between?
41
+ ]
42
+ ).freeze
43
+
44
+ def on_send(node)
45
+ return unless node.receiver&.const_name == 'Rails'
46
+
47
+ parent = node.parent
48
+ return unless parent&.predicate_method?
49
+
50
+ return if ALLOWED_LIST.include?(parent.method_name)
51
+
52
+ add_offense(parent)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -24,45 +24,69 @@ module RuboCop
24
24
 
25
25
  minimum_target_rails_version 7.1
26
26
 
27
- # @!method rails_env_local_or?(node)
28
- def_node_matcher :rails_env_local_or?, <<~PATTERN
29
- (or
30
- (send (send (const {cbase nil? } :Rails) :env) $%LOCAL_ENVIRONMENTS)
31
- (send (send (const {cbase nil? } :Rails) :env) $%LOCAL_ENVIRONMENTS)
32
- )
27
+ # @!method rails_env_local?(node)
28
+ def_node_matcher :rails_env_local?, <<~PATTERN
29
+ (send (send (const {cbase nil? } :Rails) :env) $%LOCAL_ENVIRONMENTS)
33
30
  PATTERN
34
31
 
35
- # @!method rails_env_local_and?(node)
36
- def_node_matcher :rails_env_local_and?, <<~PATTERN
37
- (and
38
- (send
39
- (send (send (const {cbase nil? } :Rails) :env) $%LOCAL_ENVIRONMENTS)
40
- :!)
41
- (send
42
- (send (send (const {cbase nil? } :Rails) :env) $%LOCAL_ENVIRONMENTS)
43
- :!)
44
- )
32
+ # @!method not_rails_env_local?(node)
33
+ def_node_matcher :not_rails_env_local?, <<~PATTERN
34
+ (send #rails_env_local? :!)
45
35
  PATTERN
46
36
 
47
37
  def on_or(node)
48
- rails_env_local_or?(node) do |*environments|
49
- next unless environments.to_set == LOCAL_ENVIRONMENTS
38
+ lhs, rhs = *node.children
39
+ return unless rails_env_local?(rhs)
50
40
 
51
- add_offense(node) do |corrector|
52
- corrector.replace(node, 'Rails.env.local?')
53
- end
41
+ nodes = [rhs]
42
+
43
+ if rails_env_local?(lhs)
44
+ nodes << lhs
45
+ elsif lhs.or_type? && rails_env_local?(lhs.rhs)
46
+ nodes << lhs.rhs
47
+ end
48
+
49
+ return unless environments(nodes).to_set == LOCAL_ENVIRONMENTS
50
+
51
+ range = offense_range(nodes)
52
+ add_offense(range) do |corrector|
53
+ corrector.replace(range, 'Rails.env.local?')
54
54
  end
55
55
  end
56
56
 
57
57
  def on_and(node)
58
- rails_env_local_and?(node) do |*environments|
59
- next unless environments.to_set == LOCAL_ENVIRONMENTS
58
+ lhs, rhs = *node.children
59
+ return unless not_rails_env_local?(rhs)
60
+
61
+ nodes = [rhs]
62
+
63
+ if not_rails_env_local?(lhs)
64
+ nodes << lhs
65
+ elsif lhs.operator_keyword? && not_rails_env_local?(lhs.rhs)
66
+ nodes << lhs.rhs
67
+ end
60
68
 
61
- add_offense(node, message: MSG_NEGATED) do |corrector|
62
- corrector.replace(node, '!Rails.env.local?')
63
- end
69
+ return unless environments(nodes).to_set == LOCAL_ENVIRONMENTS
70
+
71
+ range = offense_range(nodes)
72
+ add_offense(range, message: MSG_NEGATED) do |corrector|
73
+ corrector.replace(range, '!Rails.env.local?')
64
74
  end
65
75
  end
76
+
77
+ private
78
+
79
+ def environments(nodes)
80
+ if nodes[0].method?(:!)
81
+ nodes.map { |node| node.receiver.method_name }
82
+ else
83
+ nodes.map(&:method_name)
84
+ end
85
+ end
86
+
87
+ def offense_range(nodes)
88
+ nodes[1].source_range.begin.join(nodes[0].source_range.end)
89
+ end
66
90
  end
67
91
  end
68
92
  end
@@ -3,12 +3,13 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Rails
6
- # Checks that Rails.env is compared using `.production?`-like
6
+ # Checks that `Rails.env` is compared using `.production?`-like
7
7
  # methods instead of equality against a string or symbol.
8
8
  #
9
9
  # @example
10
10
  # # bad
11
11
  # Rails.env == 'production'
12
+ # Rails.env.to_sym == :production
12
13
  #
13
14
  # # bad, always returns false
14
15
  # Rails.env == :test
@@ -18,26 +19,40 @@ module RuboCop
18
19
  class EnvironmentComparison < Base
19
20
  extend AutoCorrector
20
21
 
21
- MSG = 'Favor `%<bang>sRails.env.%<env>s?` over `%<source>s`.'
22
+ MSG = 'Favor `%<prefer>s` over `%<source>s`.'
22
23
 
23
24
  SYM_MSG = 'Do not compare `Rails.env` with a symbol, it will always evaluate to `false`.'
24
25
 
25
26
  RESTRICT_ON_SEND = %i[== !=].freeze
26
27
 
27
- def_node_matcher :comparing_str_env_with_rails_env_on_lhs?, <<~PATTERN
28
- (send
29
- (send (const {nil? cbase} :Rails) :env)
30
- {:== :!=}
31
- $str
32
- )
28
+ def_node_matcher :comparing_env_with_rails_env_on_lhs?, <<~PATTERN
29
+ {
30
+ (send
31
+ (send (const {nil? cbase} :Rails) :env)
32
+ {:== :!=}
33
+ $str
34
+ )
35
+ (send
36
+ (send (send (const {nil? cbase} :Rails) :env) :to_sym)
37
+ {:== :!=}
38
+ $sym
39
+ )
40
+ }
33
41
  PATTERN
34
42
 
35
- def_node_matcher :comparing_str_env_with_rails_env_on_rhs?, <<~PATTERN
36
- (send
37
- $str
38
- {:== :!=}
39
- (send (const {nil? cbase} :Rails) :env)
40
- )
43
+ def_node_matcher :comparing_env_with_rails_env_on_rhs?, <<~PATTERN
44
+ {
45
+ (send
46
+ $str
47
+ {:== :!=}
48
+ (send (const {nil? cbase} :Rails) :env)
49
+ )
50
+ (send
51
+ $sym
52
+ {:== :!=}
53
+ (send (send (const {nil? cbase} :Rails) :env) :to_sym)
54
+ )
55
+ }
41
56
  PATTERN
42
57
 
43
58
  def_node_matcher :comparing_sym_env_with_rails_env_on_lhs?, <<~PATTERN
@@ -56,59 +71,52 @@ module RuboCop
56
71
  )
57
72
  PATTERN
58
73
 
59
- def_node_matcher :content, <<~PATTERN
60
- ({str sym} $_)
61
- PATTERN
62
-
63
74
  def on_send(node)
64
- if (env_node = comparing_str_env_with_rails_env_on_lhs?(node) ||
65
- comparing_str_env_with_rails_env_on_rhs?(node))
66
- env, = *env_node
67
- bang = node.method?(:!=) ? '!' : ''
68
- message = format(MSG, bang: bang, env: env, source: node.source)
69
-
70
- add_offense(node, message: message) do |corrector|
71
- autocorrect(corrector, node)
72
- end
75
+ check_env_comparison_with_rails_env(node)
76
+ check_sym_env_comparison_with_rails_env(node)
77
+ end
78
+
79
+ private
80
+
81
+ def check_env_comparison_with_rails_env(node)
82
+ return unless comparing_env_with_rails_env_on_lhs?(node) || comparing_env_with_rails_env_on_rhs?(node)
83
+
84
+ replacement = build_predicate_method(node)
85
+ message = format(MSG, prefer: replacement, source: node.source)
86
+
87
+ add_offense(node, message: message) do |corrector|
88
+ corrector.replace(node, replacement)
73
89
  end
90
+ end
74
91
 
92
+ def check_sym_env_comparison_with_rails_env(node)
75
93
  return unless comparing_sym_env_with_rails_env_on_lhs?(node) || comparing_sym_env_with_rails_env_on_rhs?(node)
76
94
 
77
95
  add_offense(node, message: SYM_MSG) do |corrector|
78
- autocorrect(corrector, node)
96
+ replacement = build_predicate_method(node)
97
+ corrector.replace(node, replacement)
79
98
  end
80
99
  end
81
100
 
82
- private
101
+ def build_predicate_method(node)
102
+ bang = node.method?(:!=) ? '!' : ''
83
103
 
84
- def autocorrect(corrector, node)
85
- replacement = build_predicate_method(node)
104
+ receiver, argument = extract_receiver_and_argument(node)
105
+ receiver = receiver.receiver if receiver.method?(:to_sym)
86
106
 
87
- corrector.replace(node, replacement)
107
+ "#{bang}#{receiver.source}.#{argument.value}?"
88
108
  end
89
109
 
90
- def build_predicate_method(node)
110
+ def extract_receiver_and_argument(node)
91
111
  if rails_env_on_lhs?(node)
92
- build_predicate_method_for_rails_env_on_lhs(node)
112
+ [node.receiver, node.first_argument]
93
113
  else
94
- build_predicate_method_for_rails_env_on_rhs(node)
114
+ [node.first_argument, node.receiver]
95
115
  end
96
116
  end
97
117
 
98
118
  def rails_env_on_lhs?(node)
99
- comparing_str_env_with_rails_env_on_lhs?(node) || comparing_sym_env_with_rails_env_on_lhs?(node)
100
- end
101
-
102
- def build_predicate_method_for_rails_env_on_lhs(node)
103
- bang = node.method?(:!=) ? '!' : ''
104
-
105
- "#{bang}#{node.receiver.source}.#{content(node.first_argument)}?"
106
- end
107
-
108
- def build_predicate_method_for_rails_env_on_rhs(node)
109
- bang = node.method?(:!=) ? '!' : ''
110
-
111
- "#{bang}#{node.first_argument.source}.#{content(node.receiver)}?"
119
+ comparing_env_with_rails_env_on_lhs?(node) || comparing_sym_env_with_rails_env_on_lhs?(node)
112
120
  end
113
121
  end
114
122
  end
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Rails
6
- # Enforces that `exit` calls are not used within a rails app.
6
+ # Enforces that `exit` and `abort` calls are not used within a rails app.
7
7
  # Valid options are instead to raise an error, break, return, or some
8
8
  # other form of stopping execution of current request.
9
9
  #
@@ -26,12 +26,15 @@ module RuboCop
26
26
  class Exit < Base
27
27
  include ConfigurableEnforcedStyle
28
28
 
29
- MSG = 'Do not use `exit` in Rails applications.'
30
- RESTRICT_ON_SEND = %i[exit exit!].freeze
29
+ MSG = 'Do not use `%<current>s` in Rails applications.'
30
+ RESTRICT_ON_SEND = %i[exit exit! abort].freeze
31
31
  EXPLICIT_RECEIVERS = %i[Kernel Process].freeze
32
32
 
33
33
  def on_send(node)
34
- add_offense(node.loc.selector) if offending_node?(node)
34
+ return unless offending_node?(node)
35
+
36
+ message = format(MSG, current: node.method_name)
37
+ add_offense(node.loc.selector, message: message)
35
38
  end
36
39
 
37
40
  private
@@ -190,7 +190,7 @@ module RuboCop
190
190
  else
191
191
  replace_with_rails_root_join(corrector, rails_root_node, argument_source)
192
192
  end
193
- node.children[rails_root_index + 1..].each { |child| corrector.remove(child) }
193
+ node.children[(rails_root_index + 1)..].each { |child| corrector.remove(child) }
194
194
  end
195
195
 
196
196
  def autocorrect_extension_after_rails_root_join_in_dstr(corrector, node, rails_root_index, extension_node)
@@ -281,7 +281,7 @@ module RuboCop
281
281
  end
282
282
 
283
283
  def extract_rails_root_join_argument_source(node, rails_root_index)
284
- node.children[rails_root_index + 1..].map(&:source).join.delete_prefix(File::SEPARATOR)
284
+ node.children[(rails_root_index + 1)..].map(&:source).join.delete_prefix(File::SEPARATOR)
285
285
  end
286
286
 
287
287
  def extension_node?(node)
@@ -46,7 +46,7 @@ module RuboCop
46
46
  private
47
47
 
48
48
  def where_method?(receiver)
49
- return false unless receiver
49
+ return false if !receiver || receiver.any_block_type?
50
50
 
51
51
  receiver.respond_to?(:method?) && receiver.method?(:where)
52
52
  end