rubocop-rails 2.17.4 → 2.18.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8a9beeaefa16cbe4afb5d598878444a835536ccda5d9b46c3e44e111513f1d8e
4
- data.tar.gz: 669a9681ce5ab1fca038229a831f7e5acae6bbdcc3a58ecfc88d65fd54ef7190
3
+ metadata.gz: 8f1cbc229165ee81ea84fc26d1c6482f917d8e8177827b139cf36974acff0176
4
+ data.tar.gz: 23cefe2f0434e5ef4c86856221f1336bfc55ffbacfd09f2dc9a24552b633d355
5
5
  SHA512:
6
- metadata.gz: 72ca38ec9a9136bfa5bd635db9290314a4d1a4c8e3942f15aa62a823885ff1a1783f884598dce6f52765db75daccf8e4054d3faecdf973da6f2c53b10dc2c153
7
- data.tar.gz: 536c7d8f5dfec22444d2d0fc4b297eac18f7b87cc6c871ce250bec58a2a6d380e814749534e5aedc47c0a66c7ae80ac8c61ffec330093c575cd1cc8dd76e4de9
6
+ metadata.gz: 59f9af07f060ff82a64bbf9db4af4d8ebb56dfada8310073bca25fde87736ef8fa0891e6f3ba997e8b847eef6218d93f25739b8022a8cb68e9aae970e8b2c674
7
+ data.tar.gz: a4415117082d7ccaeb8349f1ee31c9dba95bb6ea54bed77b176bcdd59b03cf4e2702f99c05414ff1e9028c48f96dce2f729eb2a2b98f91183cba3cb143e08894
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012-22 Bozhidar Batsov
1
+ Copyright (c) 2012-23 Bozhidar Batsov
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/config/default.yml CHANGED
@@ -46,23 +46,6 @@ Lint/NumberConversion:
46
46
  - fortnights
47
47
  - in_milliseconds
48
48
  AllowedPatterns: []
49
- # Deprecated.
50
- IgnoredMethods:
51
- - ago
52
- - from_now
53
- - second
54
- - seconds
55
- - minute
56
- - minutes
57
- - hour
58
- - hours
59
- - day
60
- - days
61
- - week
62
- - weeks
63
- - fortnight
64
- - fortnights
65
- - in_milliseconds
66
49
 
67
50
  Rails:
68
51
  Enabled: true
@@ -135,7 +118,9 @@ Rails/ActiveRecordOverride:
135
118
  Check for overriding Active Record methods instead of using
136
119
  callbacks.
137
120
  Enabled: true
121
+ Severity: warning
138
122
  VersionAdded: '0.67'
123
+ VersionChanged: '2.18'
139
124
  Include:
140
125
  - app/models/**/*.rb
141
126
 
@@ -226,6 +211,9 @@ Rails/BelongsTo:
226
211
  Description: >-
227
212
  Use `optional: true` instead of `required: false` for
228
213
  `belongs_to` relations.
214
+ Reference:
215
+ - https://guides.rubyonrails.org/5_0_release_notes.html
216
+ - https://github.com/rails/rails/pull/18937
229
217
  Enabled: true
230
218
  VersionAdded: '0.62'
231
219
 
@@ -244,6 +232,9 @@ Rails/Blank:
244
232
 
245
233
  Rails/BulkChangeTable:
246
234
  Description: 'Check whether alter queries are combinable.'
235
+ Reference:
236
+ - https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-change_table
237
+ - https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html
247
238
  Enabled: true
248
239
  VersionAdded: '0.57'
249
240
  Database: null
@@ -330,9 +321,10 @@ Rails/DelegateAllowBlank:
330
321
  Rails/DeprecatedActiveModelErrorsMethods:
331
322
  Description: 'Avoid manipulating ActiveModel errors hash directly.'
332
323
  Enabled: pending
324
+ Severity: warning
333
325
  Safe: false
334
326
  VersionAdded: '2.14'
335
- VersionChanged: '2.15'
327
+ VersionChanged: '2.18'
336
328
 
337
329
  Rails/DotSeparatedKeys:
338
330
  Description: 'Enforces the use of dot-separated keys instead of `:scope` options in `I18n` translation methods.'
@@ -343,12 +335,16 @@ Rails/DotSeparatedKeys:
343
335
  Rails/DuplicateAssociation:
344
336
  Description: "Don't repeat associations in a model."
345
337
  Enabled: pending
338
+ Severity: warning
346
339
  VersionAdded: '2.14'
340
+ VersionChanged: '2.18'
347
341
 
348
342
  Rails/DuplicateScope:
349
343
  Description: 'Multiple scopes share this same where clause.'
350
344
  Enabled: pending
345
+ Severity: warning
351
346
  VersionAdded: '2.14'
347
+ VersionChanged: '2.18'
352
348
 
353
349
  Rails/DurationArithmetic:
354
350
  Description: 'Do not use duration as arithmetic operand with `Time.current`.'
@@ -463,7 +459,7 @@ Rails/FindById:
463
459
  VersionAdded: '2.7'
464
460
 
465
461
  Rails/FindEach:
466
- Description: 'Prefer all.find_each over all.find.'
462
+ Description: 'Prefer all.find_each over all.each.'
467
463
  StyleGuide: 'https://rails.rubystyle.guide#find-each'
468
464
  Enabled: true
469
465
  VersionAdded: '0.30'
@@ -477,13 +473,6 @@ Rails/FindEach:
477
473
  - select
478
474
  - lock
479
475
  AllowedPatterns: []
480
- # Deprecated.
481
- IgnoredMethods:
482
- # Methods that don't work well with `find_each`.
483
- - order
484
- - limit
485
- - select
486
- - lock
487
476
 
488
477
  Rails/FreezeTime:
489
478
  Description: 'Prefer `freeze_time` over `travel_to` with an argument of the current time.'
@@ -592,6 +581,9 @@ Rails/Inquiry:
592
581
 
593
582
  Rails/InverseOf:
594
583
  Description: 'Checks for associations where the inverse cannot be determined automatically.'
584
+ Reference:
585
+ - https://guides.rubyonrails.org/association_basics.html#bi-directional-associations
586
+ - https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#module-ActiveRecord::Associations::ClassMethods-label-Setting+Inverses
595
587
  Enabled: true
596
588
  VersionAdded: '0.52'
597
589
  IgnoreScopes: false
@@ -695,7 +687,9 @@ Rails/Pluck:
695
687
  Description: 'Prefer `pluck` over `map { ... }`.'
696
688
  StyleGuide: 'https://rails.rubystyle.guide#pluck'
697
689
  Enabled: 'pending'
690
+ Safe: false
698
691
  VersionAdded: '2.7'
692
+ VersionChanged: '2.18'
699
693
 
700
694
  Rails/PluckId:
701
695
  Description: 'Use `ids` instead of `pluck(:id)` or `pluck(primary_key)`.'
@@ -847,6 +841,17 @@ Rails/RequireDependency:
847
841
  Enabled: false
848
842
  VersionAdded: '2.10'
849
843
 
844
+ Rails/ResponseParsedBody:
845
+ Description: Prefer `response.parsed_body` to `JSON.parse(response.body)`.
846
+ Enabled: pending
847
+ SafeAutoCorrect: false
848
+ VersionAdded: '2.18'
849
+ Include:
850
+ - spec/controllers/**/*.rb
851
+ - spec/requests/**/*.rb
852
+ - test/controllers/**/*.rb
853
+ - test/integration/**/*.rb
854
+
850
855
  Rails/ReversibleMigration:
851
856
  Description: 'Checks whether the change method of the migration file is reversible.'
852
857
  StyleGuide: 'https://rails.rubystyle.guide#reversible-migration'
@@ -1038,10 +1043,14 @@ Rails/TopLevelHashWithIndifferentAccess:
1038
1043
  Description: 'Identifies top-level `HashWithIndifferentAccess`.'
1039
1044
  Reference: 'https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#top-level-hashwithindifferentaccess-is-soft-deprecated'
1040
1045
  Enabled: pending
1046
+ Severity: warning
1041
1047
  VersionAdded: '2.16'
1048
+ VersionChanged: '2.18'
1042
1049
 
1043
1050
  Rails/TransactionExitStatement:
1044
1051
  Description: 'Avoid the usage of `return`, `break` and `throw` in transaction blocks.'
1052
+ Reference:
1053
+ - https://github.com/rails/rails/commit/15aa4200e083
1045
1054
  Enabled: pending
1046
1055
  VersionAdded: '2.14'
1047
1056
 
@@ -1066,7 +1075,9 @@ Rails/UniqueValidationWithoutIndex:
1066
1075
  Rails/UnknownEnv:
1067
1076
  Description: 'Use correct environment name.'
1068
1077
  Enabled: true
1078
+ Severity: warning
1069
1079
  VersionAdded: '0.51'
1080
+ VersionChanged: '2.18'
1070
1081
  Environments:
1071
1082
  - development
1072
1083
  - test
@@ -1121,12 +1132,27 @@ Rails/WhereNot:
1121
1132
  Rails/WhereNotWithMultipleConditions:
1122
1133
  Description: 'Do not use `where.not(...)` with multiple conditions.'
1123
1134
  Enabled: 'pending'
1135
+ Severity: warning
1124
1136
  VersionAdded: '2.17'
1137
+ VersionChanged: '2.18'
1125
1138
 
1126
1139
  # Accept `redirect_to(...) and return` and similar cases.
1127
1140
  Style/AndOr:
1128
1141
  EnforcedStyle: conditionals
1129
1142
 
1143
+ Style/FormatStringToken:
1144
+ AllowedMethods:
1145
+ - redirect
1146
+
1147
+ Style/InverseMethods:
1148
+ # `InverseMethods` are methods that can be inverted by a not (`not` or `!`)
1149
+ # The relationship of inverse methods only needs to be defined in one direction.
1150
+ # Keys and values both need to be defined as symbols.
1151
+ InverseMethods:
1152
+ :present?: :blank?
1153
+ :include?: :exclude?
1154
+ :valid?: :invalid?
1155
+
1130
1156
  Style/SymbolProc:
1131
1157
  AllowedMethods:
1132
1158
  - define_method
@@ -67,9 +67,11 @@ module RuboCop
67
67
  private
68
68
 
69
69
  def followed_by_render?(flash_node)
70
- flash_assigment_node = find_ancestor(flash_node, type: :send)
71
- context = flash_assigment_node
70
+ flash_assignment_node = find_ancestor(flash_node, type: :send)
71
+ context = flash_assignment_node
72
72
  if (node = context.each_ancestor(:if, :rescue).first)
73
+ return false if use_redirect_to?(context)
74
+
73
75
  context = node
74
76
  elsif context.right_siblings.empty?
75
77
  return true
@@ -95,6 +97,12 @@ module RuboCop
95
97
  def_node || block_node
96
98
  end
97
99
 
100
+ def use_redirect_to?(context)
101
+ context.right_siblings.compact.any? do |sibling|
102
+ sibling.send_type? && sibling.method?(:redirect_to)
103
+ end
104
+ end
105
+
98
106
  def find_ancestor(node, type:)
99
107
  node.each_ancestor(type).first
100
108
  end
@@ -30,7 +30,7 @@ module RuboCop
30
30
 
31
31
  def_node_matcher :action_controller_test_case?, <<~PATTERN
32
32
  (class
33
- (const {nil? cbase} _)
33
+ (const _ _)
34
34
  (const (const {nil? cbase} :ActionController) :TestCase) _)
35
35
  PATTERN
36
36
 
@@ -26,6 +26,8 @@ module RuboCop
26
26
  RESTRICT_ON_SEND = ALIASES.keys.freeze
27
27
 
28
28
  def on_send(node)
29
+ return if node.arguments.empty?
30
+
29
31
  method_name = node.method_name
30
32
  alias_method = ALIASES[method_name]
31
33
 
@@ -47,9 +47,6 @@ module RuboCop
47
47
  # class Post < ApplicationRecord
48
48
  # belongs_to :blog, optional: false
49
49
  # end
50
- #
51
- # @see https://guides.rubyonrails.org/5_0_release_notes.html
52
- # @see https://github.com/rails/rails/pull/18937
53
50
  class BelongsTo < Base
54
51
  extend AutoCorrector
55
52
  extend TargetRailsVersion
@@ -8,7 +8,7 @@ module RuboCop
8
8
  #
9
9
  # Interaction with `Style/UnlessElse`:
10
10
  # The configuration of `NotPresent` will not produce an offense in the
11
- # context of `unless else` if `Style/UnlessElse` is inabled. This is
11
+ # context of `unless else` if `Style/UnlessElse` is enabled. This is
12
12
  # to prevent interference between the autocorrection of the two cops.
13
13
  #
14
14
  # @safety
@@ -62,9 +62,6 @@ module RuboCop
62
62
  # t.string :nickname
63
63
  # end
64
64
  # end
65
- #
66
- # @see https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-change_table
67
- # @see https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html
68
65
  class BulkChangeTable < Base
69
66
  MSG_FOR_CHANGE_TABLE = <<~MSG.chomp
70
67
  You can combine alter queries using `bulk: true` options.
@@ -216,7 +213,7 @@ module RuboCop
216
213
  true
217
214
  when POSTGRESQL
218
215
  # Add bulk alter support for PostgreSQL in 5.2.0
219
- # @see https://github.com/rails/rails/pull/31331
216
+ # See: https://github.com/rails/rails/pull/31331
220
217
  target_rails_version >= 5.2
221
218
  else
222
219
  false
@@ -160,7 +160,7 @@ module RuboCop
160
160
  end
161
161
 
162
162
  def model_file?
163
- processed_source.buffer.name.include?('/models/')
163
+ processed_source.file_path.include?('/models/')
164
164
  end
165
165
  end
166
166
  end
@@ -26,6 +26,9 @@ module RuboCop
26
26
  #
27
27
  class FreezeTime < Base
28
28
  extend AutoCorrector
29
+ extend TargetRailsVersion
30
+
31
+ minimum_target_rails_version 5.2
29
32
 
30
33
  MSG = 'Use `freeze_time` instead of `travel_to`.'
31
34
  NOW_METHODS = %i[now new current].freeze
@@ -41,11 +41,11 @@ module RuboCop
41
41
  PATTERN
42
42
 
43
43
  def_node_matcher :association_without_options?, <<~PATTERN
44
- (send nil? {:has_many :has_one} _)
44
+ (send _ {:has_many :has_one} _)
45
45
  PATTERN
46
46
 
47
47
  def_node_matcher :association_with_options?, <<~PATTERN
48
- (send nil? {:has_many :has_one} ... (hash $...))
48
+ (send _ {:has_many :has_one} ... (hash $...))
49
49
  PATTERN
50
50
 
51
51
  def_node_matcher :dependent_option?, <<~PATTERN
@@ -35,8 +35,6 @@ module RuboCop
35
35
  # skip_before_action :login_required,
36
36
  # if: -> { trusted_origin? && action_name != "admin" }
37
37
  # end
38
- #
39
- # @see https://api.rubyonrails.org/classes/AbstractController/Callbacks/ClassMethods.html#method-i-_normalize_callback_options
40
38
  class IgnoredSkipActionFilterOption < Base
41
39
  MSG = <<~MSG.chomp.freeze
42
40
  `%<ignore>s` option will be ignored when `%<prefer>s` and `%<ignore>s` are used together.
@@ -137,9 +137,6 @@ module RuboCop
137
137
  # class Blog < ApplicationRecord
138
138
  # has_many :posts, -> { order(published_at: :desc) }
139
139
  # end
140
- #
141
- # @see https://guides.rubyonrails.org/association_basics.html#bi-directional-associations
142
- # @see https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#module-ActiveRecord::Associations::ClassMethods-label-Setting+Inverses
143
140
  class InverseOf < Base
144
141
  SPECIFY_MSG = 'Specify an `:inverse_of` option.'
145
142
  NIL_MSG = 'You specified `inverse_of: nil`, you probably meant to use `inverse_of: false`.'
@@ -144,19 +144,29 @@ module RuboCop
144
144
  end
145
145
 
146
146
  def aliased_action_methods(node, defined_methods)
147
- alias_methods = node.each_child_node(:send).select { |send_node| send_node.method?(:alias_method) }
148
-
149
- hash_of_alias_methods = alias_methods.each_with_object({}) do |alias_method, result|
150
- result[alias_method.last_argument.value] = alias_method.first_argument.value
151
- end
152
-
147
+ alias_methods = alias_methods(node)
153
148
  defined_methods.each_with_object([]) do |defined_method, aliased_method|
154
- if (new_method_name = hash_of_alias_methods[defined_method])
149
+ if (new_method_name = alias_methods[defined_method])
155
150
  aliased_method << new_method_name
156
151
  end
157
152
  end
158
153
  end
159
154
 
155
+ def alias_methods(node)
156
+ result = {}
157
+ node.each_child_node(:send, :alias) do |child_node|
158
+ case child_node.type
159
+ when :send
160
+ if child_node.method?(:alias_method)
161
+ result[child_node.last_argument.value] = child_node.first_argument.value
162
+ end
163
+ when :alias
164
+ result[child_node.old_identifier.value] = child_node.new_identifier.value
165
+ end
166
+ end
167
+ result
168
+ end
169
+
160
170
  # @param node [RuboCop::AST::Node]
161
171
  # @return [Array<Symbol>]
162
172
  def array_values(node) # rubocop:disable Metrics/MethodLength
@@ -26,7 +26,7 @@ module RuboCop
26
26
  RESTRICT_ON_SEND = %i[!].freeze
27
27
 
28
28
  def_node_matcher :negate_include_call?, <<~PATTERN
29
- (send (send $_ :include? $_) :!)
29
+ (send (send $!nil? :include? $_) :!)
30
30
  PATTERN
31
31
 
32
32
  def on_send(node)
@@ -21,7 +21,7 @@ module RuboCop
21
21
  RESTRICT_ON_SEND = %i[add_column add_reference].freeze
22
22
 
23
23
  def_node_matcher :add_not_null_column?, <<~PATTERN
24
- (send nil? :add_column _ _ _ (hash $...))
24
+ (send nil? :add_column _ _ $_ (hash $...))
25
25
  PATTERN
26
26
 
27
27
  def_node_matcher :add_not_null_reference?, <<~PATTERN
@@ -44,17 +44,20 @@ module RuboCop
44
44
  private
45
45
 
46
46
  def check_add_column(node)
47
- pairs = add_not_null_column?(node)
48
- check_pairs(pairs)
47
+ add_not_null_column?(node) do |type, pairs|
48
+ return if type.value == :virtual || type.value == 'virtual'
49
+
50
+ check_pairs(pairs)
51
+ end
49
52
  end
50
53
 
51
54
  def check_add_reference(node)
52
- pairs = add_not_null_reference?(node)
53
- check_pairs(pairs)
55
+ add_not_null_reference?(node) do |pairs|
56
+ check_pairs(pairs)
57
+ end
54
58
  end
55
59
 
56
60
  def check_pairs(pairs)
57
- return unless pairs
58
61
  return if pairs.any? { |pair| default_option?(pair) }
59
62
 
60
63
  null_false = pairs.find { |pair| null_false?(pair) }
@@ -9,6 +9,18 @@ module RuboCop
9
9
  # element in an enumerable. When called on an Active Record relation, it
10
10
  # results in a more efficient query that only selects the necessary key.
11
11
  #
12
+ # @safety
13
+ # This cop is unsafe because model can use column aliases.
14
+ #
15
+ # [source,ruby]
16
+ # ----
17
+ # # Original code
18
+ # User.select('name AS nickname').map { |user| user[:nickname] } # => array of nicknames
19
+ #
20
+ # # After autocorrection
21
+ # User.select('name AS nickname').pluck(:nickname) # => raises ActiveRecord::StatementInvalid
22
+ # ----
23
+ #
12
24
  # @example
13
25
  # # bad
14
26
  # Post.published.map { |post| post[:title] }
@@ -112,10 +112,10 @@ module RuboCop
112
112
  end
113
113
 
114
114
  def current(node)
115
- if node.source.include?("\n")
115
+ if !node.ternary? && node.source.include?("\n")
116
116
  "#{node.loc.keyword.with(end_pos: node.condition.loc.selector.end_pos).source} ... end"
117
117
  else
118
- node.source
118
+ node.source.gsub(/\n\s*/, ' ')
119
119
  end
120
120
  end
121
121
 
@@ -8,7 +8,7 @@ module RuboCop
8
8
  #
9
9
  # Interaction with `Style/UnlessElse`:
10
10
  # The configuration of `NotBlank` will not produce an offense in the
11
- # context of `unless else` if `Style/UnlessElse` is inabled. This is
11
+ # context of `unless else` if `Style/UnlessElse` is enabled. This is
12
12
  # to prevent interference between the autocorrection of the two cops.
13
13
  #
14
14
  # @example NotNilAndNotEmpty: true (default)
@@ -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's autocorrection is unsafe because Content-Type may not be `application/json`. For example, the
10
+ # proprietary Content-Type provided by corporate entities such as `application/vnd.github+json` is not
11
+ # supported at `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
 
@@ -48,6 +48,7 @@ module RuboCop
48
48
  SQL = 'SQL'
49
49
  SQUISH = '.squish'
50
50
  MSG = 'Use `%<expect>s` instead of `%<current>s`.'
51
+ SQL_IDENTIFIER_MARKERS = /(".+?")|('.+?')|(\[.+?\])/.freeze
51
52
 
52
53
  def on_heredoc(node)
53
54
  return unless offense_detected?(node)
@@ -60,7 +61,7 @@ module RuboCop
60
61
  private
61
62
 
62
63
  def offense_detected?(node)
63
- sql_heredoc?(node) && !using_squish?(node)
64
+ sql_heredoc?(node) && !using_squish?(node) && !singleline_comments_present?(node)
64
65
  end
65
66
 
66
67
  def sql_heredoc?(node)
@@ -71,6 +72,12 @@ module RuboCop
71
72
  node.parent&.send_type? && node.parent&.method?(:squish)
72
73
  end
73
74
 
75
+ def singleline_comments_present?(node)
76
+ sql = node.children.map { |c| c.is_a?(String) ? c : c.source }.join('\n')
77
+
78
+ sql.gsub(SQL_IDENTIFIER_MARKERS, '').include?('--')
79
+ end
80
+
74
81
  def message(node)
75
82
  format(MSG, expect: "#{node.source}#{SQUISH}", current: node.source)
76
83
  end
@@ -45,8 +45,6 @@ module RuboCop
45
45
  # # Commit
46
46
  # next if user.active?
47
47
  # end
48
- #
49
- # @see https://github.com/rails/rails/commit/15aa4200e083
50
48
  class TransactionExitStatement < Base
51
49
  MSG = <<~MSG.chomp
52
50
  Exit statement `%<statement>s` is not allowed. Use `raise` (rollback) or `next` (commit).
@@ -28,12 +28,16 @@ module RuboCop
28
28
  (send self :ignored_columns= $array)
29
29
  PATTERN
30
30
 
31
+ def_node_matcher :appended_ignored_columns, <<~PATTERN
32
+ (op-asgn (send self :ignored_columns) :+ $array)
33
+ PATTERN
34
+
31
35
  def_node_matcher :column_name, <<~PATTERN
32
36
  ({str sym} $_)
33
37
  PATTERN
34
38
 
35
39
  def on_send(node)
36
- return unless (columns = ignored_columns(node))
40
+ return unless (columns = ignored_columns(node) || appended_ignored_columns(node))
37
41
  return unless schema
38
42
 
39
43
  table = table(node)
@@ -43,6 +47,7 @@ module RuboCop
43
47
  check_column_existence(column_node, table)
44
48
  end
45
49
  end
50
+ alias on_op_asgn on_send
46
51
 
47
52
  private
48
53
 
@@ -99,6 +99,7 @@ require_relative 'rails/render_inline'
99
99
  require_relative 'rails/render_plain_text'
100
100
  require_relative 'rails/request_referer'
101
101
  require_relative 'rails/require_dependency'
102
+ require_relative 'rails/response_parsed_body'
102
103
  require_relative 'rails/reversible_migration'
103
104
  require_relative 'rails/reversible_migration_method_definition'
104
105
  require_relative 'rails/root_join_chain'
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module Rails
5
5
  # This module holds the RuboCop Rails version information.
6
6
  module Version
7
- STRING = '2.17.4'
7
+ STRING = '2.18.0'
8
8
 
9
9
  def self.document_version
10
10
  STRING.match('\d+\.\d+').to_s
data/lib/rubocop/rails.rb CHANGED
@@ -5,7 +5,7 @@ module RuboCop
5
5
  module Rails
6
6
  PROJECT_ROOT = Pathname.new(__dir__).parent.parent.expand_path.freeze
7
7
  CONFIG_DEFAULT = PROJECT_ROOT.join('config', 'default.yml').freeze
8
- CONFIG = YAML.safe_load(CONFIG_DEFAULT.read).freeze
8
+ CONFIG = YAML.safe_load(CONFIG_DEFAULT.read, permitted_classes: [Regexp, Symbol]).freeze
9
9
 
10
10
  private_constant(:CONFIG_DEFAULT, :PROJECT_ROOT)
11
11
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.17.4
4
+ version: 2.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2022-12-25 00:00:00.000000000 Z
13
+ date: 2023-02-25 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -173,6 +173,7 @@ files:
173
173
  - lib/rubocop/cop/rails/render_plain_text.rb
174
174
  - lib/rubocop/cop/rails/request_referer.rb
175
175
  - lib/rubocop/cop/rails/require_dependency.rb
176
+ - lib/rubocop/cop/rails/response_parsed_body.rb
176
177
  - lib/rubocop/cop/rails/reversible_migration.rb
177
178
  - lib/rubocop/cop/rails/reversible_migration_method_definition.rb
178
179
  - lib/rubocop/cop/rails/root_join_chain.rb
@@ -217,7 +218,7 @@ metadata:
217
218
  homepage_uri: https://docs.rubocop.org/rubocop-rails/
218
219
  changelog_uri: https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md
219
220
  source_code_uri: https://github.com/rubocop/rubocop-rails/
220
- documentation_uri: https://docs.rubocop.org/rubocop-rails/2.17/
221
+ documentation_uri: https://docs.rubocop.org/rubocop-rails/2.18/
221
222
  bug_tracker_uri: https://github.com/rubocop/rubocop-rails/issues
222
223
  rubygems_mfa_required: 'true'
223
224
  post_install_message:
@@ -235,7 +236,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
235
236
  - !ruby/object:Gem::Version
236
237
  version: '0'
237
238
  requirements: []
238
- rubygems_version: 3.3.26
239
+ rubygems_version: 3.4.1
239
240
  signing_key:
240
241
  specification_version: 4
241
242
  summary: Automatic Rails code style checking tool.