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 +4 -4
- data/LICENSE.txt +1 -1
- data/config/default.yml +52 -26
- data/lib/rubocop/cop/rails/action_controller_flash_before_render.rb +10 -2
- data/lib/rubocop/cop/rails/action_controller_test_case.rb +1 -1
- data/lib/rubocop/cop/rails/active_record_aliases.rb +2 -0
- data/lib/rubocop/cop/rails/belongs_to.rb +0 -3
- data/lib/rubocop/cop/rails/blank.rb +1 -1
- data/lib/rubocop/cop/rails/bulk_change_table.rb +1 -4
- data/lib/rubocop/cop/rails/deprecated_active_model_errors_methods.rb +1 -1
- data/lib/rubocop/cop/rails/freeze_time.rb +3 -0
- data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +2 -2
- data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +0 -2
- data/lib/rubocop/cop/rails/inverse_of.rb +0 -3
- data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +17 -7
- data/lib/rubocop/cop/rails/negate_include.rb +1 -1
- data/lib/rubocop/cop/rails/not_null_column.rb +9 -6
- data/lib/rubocop/cop/rails/pluck.rb +12 -0
- data/lib/rubocop/cop/rails/presence.rb +2 -2
- data/lib/rubocop/cop/rails/present.rb +1 -1
- data/lib/rubocop/cop/rails/response_parsed_body.rb +57 -0
- data/lib/rubocop/cop/rails/reversible_migration.rb +4 -29
- data/lib/rubocop/cop/rails/squished_sql_heredocs.rb +8 -1
- data/lib/rubocop/cop/rails/transaction_exit_statement.rb +0 -2
- data/lib/rubocop/cop/rails/unused_ignored_columns.rb +6 -1
- data/lib/rubocop/cop/rails_cops.rb +1 -0
- data/lib/rubocop/rails/version.rb +1 -1
- data/lib/rubocop/rails.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f1cbc229165ee81ea84fc26d1c6482f917d8e8177827b139cf36974acff0176
|
4
|
+
data.tar.gz: 23cefe2f0434e5ef4c86856221f1336bfc55ffbacfd09f2dc9a24552b633d355
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59f9af07f060ff82a64bbf9db4af4d8ebb56dfada8310073bca25fde87736ef8fa0891e6f3ba997e8b847eef6218d93f25739b8022a8cb68e9aae970e8b2c674
|
7
|
+
data.tar.gz: a4415117082d7ccaeb8349f1ee31c9dba95bb6ea54bed77b176bcdd59b03cf4e2702f99c05414ff1e9028c48f96dce2f729eb2a2b98f91183cba3cb143e08894
|
data/LICENSE.txt
CHANGED
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.
|
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.
|
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
|
-
|
71
|
-
context =
|
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
|
@@ -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
|
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
|
-
#
|
216
|
+
# See: https://github.com/rails/rails/pull/31331
|
220
217
|
target_rails_version >= 5.2
|
221
218
|
else
|
222
219
|
false
|
@@ -41,11 +41,11 @@ module RuboCop
|
|
41
41
|
PATTERN
|
42
42
|
|
43
43
|
def_node_matcher :association_without_options?, <<~PATTERN
|
44
|
-
(send
|
44
|
+
(send _ {:has_many :has_one} _)
|
45
45
|
PATTERN
|
46
46
|
|
47
47
|
def_node_matcher :association_with_options?, <<~PATTERN
|
48
|
-
(send
|
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
|
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 =
|
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
|
@@ -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
|
-
|
48
|
-
|
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
|
-
|
53
|
-
|
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
|
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
|
-
#
|
20
|
-
# t.
|
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
|
-
#
|
27
|
-
#
|
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'
|
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.
|
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:
|
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.
|
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.
|
239
|
+
rubygems_version: 3.4.1
|
239
240
|
signing_key:
|
240
241
|
specification_version: 4
|
241
242
|
summary: Automatic Rails code style checking tool.
|