rubocop-rails 2.25.1 → 2.26.1
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/config/default.yml +17 -3
- data/lib/rubocop/cop/rails/action_controller_flash_before_render.rb +5 -5
- data/lib/rubocop/cop/rails/action_order.rb +1 -5
- data/lib/rubocop/cop/rails/active_record_callbacks_order.rb +1 -5
- data/lib/rubocop/cop/rails/application_record.rb +4 -0
- data/lib/rubocop/cop/rails/bulk_change_table.rb +2 -2
- data/lib/rubocop/cop/rails/compact_blank.rb +25 -8
- data/lib/rubocop/cop/rails/date.rb +2 -2
- data/lib/rubocop/cop/rails/enum_hash.rb +31 -8
- data/lib/rubocop/cop/rails/enum_syntax.rb +126 -0
- data/lib/rubocop/cop/rails/enum_uniqueness.rb +29 -7
- data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +1 -1
- data/lib/rubocop/cop/rails/pluck_in_where.rb +17 -8
- data/lib/rubocop/cop/rails/pluralization_grammar.rb +29 -15
- data/lib/rubocop/cop/rails/present.rb +0 -2
- data/lib/rubocop/cop/rails/redundant_active_record_all_method.rb +0 -29
- data/lib/rubocop/cop/rails/redundant_presence_validation_on_belongs_to.rb +9 -0
- data/lib/rubocop/cop/rails/render_plain_text.rb +6 -3
- data/lib/rubocop/cop/rails/root_pathname_methods.rb +15 -11
- data/lib/rubocop/cop/rails/skips_model_validations.rb +4 -2
- data/lib/rubocop/cop/rails/validation.rb +1 -1
- data/lib/rubocop/cop/rails/where_equals.rb +28 -12
- data/lib/rubocop/cop/rails/where_not.rb +11 -6
- data/lib/rubocop/cop/rails/where_range.rb +6 -1
- data/lib/rubocop/cop/rails_cops.rb +1 -0
- data/lib/rubocop/rails/version.rb +1 -1
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5544e111596dd242dd77d44afe7e6999d1c339d3d6f6a03187a148495c836d1
|
4
|
+
data.tar.gz: 7da9bdcc53ee453774708dadfd1df0d1913736f78288781fa50ebfd465cc4042
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b9677c9549dc593121b1832432afdc18cc1b6f47435d4b4a39f4bc2e73ebb660252cd747dd0deaa0fe293d9e4c165467aad80115b1306e007d33d1c2c151ecbb
|
7
|
+
data.tar.gz: 1508e3913f537195067ff8129845729251043ad7bedea2c19879c24882036f2d15b31c0af6178d91dd64d21f5d7468460e9e3fbacb2ce4e499be76a03efb59dd
|
data/config/default.yml
CHANGED
@@ -212,7 +212,9 @@ Rails/ApplicationRecord:
|
|
212
212
|
Enabled: true
|
213
213
|
SafeAutoCorrect: false
|
214
214
|
VersionAdded: '0.49'
|
215
|
-
VersionChanged: '2.
|
215
|
+
VersionChanged: '2.26'
|
216
|
+
Exclude:
|
217
|
+
- db/**/*.rb
|
216
218
|
|
217
219
|
Rails/ArelStar:
|
218
220
|
Description: 'Enforces `Arel.star` instead of `"*"` for expanded columns.'
|
@@ -424,6 +426,14 @@ Rails/EnumHash:
|
|
424
426
|
Include:
|
425
427
|
- app/models/**/*.rb
|
426
428
|
|
429
|
+
Rails/EnumSyntax:
|
430
|
+
Description: 'Use positional arguments over keyword arguments when defining enums.'
|
431
|
+
Enabled: pending
|
432
|
+
Severity: warning
|
433
|
+
VersionAdded: '2.26'
|
434
|
+
Include:
|
435
|
+
- app/models/**/*.rb
|
436
|
+
|
427
437
|
Rails/EnumUniqueness:
|
428
438
|
Description: 'Avoid duplicate integers in hash-syntax `enum` declaration.'
|
429
439
|
Enabled: true
|
@@ -1185,12 +1195,12 @@ Rails/Validation:
|
|
1185
1195
|
- app/models/**/*.rb
|
1186
1196
|
|
1187
1197
|
Rails/WhereEquals:
|
1188
|
-
Description: 'Pass conditions to `where` as a hash instead of manually constructing SQL.'
|
1198
|
+
Description: 'Pass conditions to `where` and `where.not` as a hash instead of manually constructing SQL.'
|
1189
1199
|
StyleGuide: 'https://rails.rubystyle.guide/#hash-conditions'
|
1190
1200
|
Enabled: 'pending'
|
1191
1201
|
SafeAutoCorrect: false
|
1192
1202
|
VersionAdded: '2.9'
|
1193
|
-
VersionChanged: '2.
|
1203
|
+
VersionChanged: '2.26'
|
1194
1204
|
|
1195
1205
|
Rails/WhereExists:
|
1196
1206
|
Description: 'Prefer `exists?(...)` over `where(...).exists?`.'
|
@@ -1234,6 +1244,10 @@ Rails/WhereRange:
|
|
1234
1244
|
Style/AndOr:
|
1235
1245
|
EnforcedStyle: conditionals
|
1236
1246
|
|
1247
|
+
Style/CollectionCompact:
|
1248
|
+
AllowedReceivers:
|
1249
|
+
- params
|
1250
|
+
|
1237
1251
|
Style/FormatStringToken:
|
1238
1252
|
AllowedMethods:
|
1239
1253
|
- redirect
|
@@ -72,13 +72,13 @@ module RuboCop
|
|
72
72
|
if (node = context.each_ancestor(:if, :rescue).first)
|
73
73
|
return false if use_redirect_to?(context)
|
74
74
|
|
75
|
-
context = node
|
76
|
-
elsif context.right_siblings.empty?
|
77
|
-
return true
|
75
|
+
context = node.rescue_type? ? node.parent : node
|
78
76
|
end
|
79
|
-
context = context.right_siblings
|
80
77
|
|
81
|
-
context.
|
78
|
+
siblings = context.right_siblings
|
79
|
+
return true if siblings.empty?
|
80
|
+
|
81
|
+
siblings.compact.any? do |render_candidate|
|
82
82
|
render?(render_candidate)
|
83
83
|
end
|
84
84
|
end
|
@@ -92,11 +92,7 @@ module RuboCop
|
|
92
92
|
end
|
93
93
|
|
94
94
|
def range_with_comments(node)
|
95
|
-
|
96
|
-
# Using `RuboCop::Ext::Comment#source_range` requires RuboCop > 1.46,
|
97
|
-
# which introduces https://github.com/rubocop/rubocop/pull/11630.
|
98
|
-
ranges = [node, *processed_source.ast_with_comments[node]].map { |comment| comment.loc.expression }
|
99
|
-
# rubocop:enable InternalAffairs/LocationExpression
|
95
|
+
ranges = [node, *processed_source.ast_with_comments[node]].map(&:source_range)
|
100
96
|
ranges.reduce do |result, range|
|
101
97
|
add_range(result, range)
|
102
98
|
end
|
@@ -123,11 +123,7 @@ module RuboCop
|
|
123
123
|
end
|
124
124
|
|
125
125
|
def inline_comment?(comment)
|
126
|
-
|
127
|
-
# Using `RuboCop::Ext::Comment#source_range` requires RuboCop > 1.46,
|
128
|
-
# which introduces https://github.com/rubocop/rubocop/pull/11630.
|
129
|
-
!comment_line?(comment.loc.expression.source_line)
|
130
|
-
# rubocop:enable InternalAffairs/LocationExpression
|
126
|
+
!comment_line?(comment.source_range.source_line)
|
131
127
|
end
|
132
128
|
|
133
129
|
def start_line_position(node)
|
@@ -5,6 +5,10 @@ module RuboCop
|
|
5
5
|
module Rails
|
6
6
|
# Checks that models subclass `ApplicationRecord` with Rails 5.0.
|
7
7
|
#
|
8
|
+
# It is a common practice to define models inside migrations in order to retain forward
|
9
|
+
# compatibility by avoiding loading any application code. And so migration files are excluded
|
10
|
+
# by default for this cop.
|
11
|
+
#
|
8
12
|
# @safety
|
9
13
|
# This cop's autocorrection is unsafe because it may let the logic from `ApplicationRecord`
|
10
14
|
# sneak into an Active Record model that is not purposed to inherit logic common among other
|
@@ -140,9 +140,9 @@ module RuboCop
|
|
140
140
|
return unless support_bulk_alter?
|
141
141
|
return unless node.command?(:change_table)
|
142
142
|
return if include_bulk_options?(node)
|
143
|
-
return unless node.block_node
|
143
|
+
return unless (body = node.block_node&.body)
|
144
144
|
|
145
|
-
send_nodes = send_nodes_from_change_table_block(
|
145
|
+
send_nodes = send_nodes_from_change_table_block(body)
|
146
146
|
|
147
147
|
add_offense_for_change_table(node) if count_transformations(send_nodes) > 1
|
148
148
|
end
|
@@ -16,7 +16,6 @@ module RuboCop
|
|
16
16
|
# And `compact_blank!` has different implementations for `Array`, `Hash`, and
|
17
17
|
# `ActionController::Parameters`.
|
18
18
|
# `Array#compact_blank!`, `Hash#compact_blank!` are equivalent to `delete_if(&:blank?)`.
|
19
|
-
# `ActionController::Parameters#compact_blank!` is equivalent to `reject!(&:blank?)`.
|
20
19
|
# If the cop makes a mistake, autocorrected code may get unexpected behavior.
|
21
20
|
#
|
22
21
|
# @example
|
@@ -24,6 +23,8 @@ module RuboCop
|
|
24
23
|
# # bad
|
25
24
|
# collection.reject(&:blank?)
|
26
25
|
# collection.reject { |_k, v| v.blank? }
|
26
|
+
# collection.select(&:present?)
|
27
|
+
# collection.select { |_k, v| v.present? }
|
27
28
|
#
|
28
29
|
# # good
|
29
30
|
# collection.compact_blank
|
@@ -31,8 +32,8 @@ module RuboCop
|
|
31
32
|
# # bad
|
32
33
|
# collection.delete_if(&:blank?) # Same behavior as `Array#compact_blank!` and `Hash#compact_blank!`
|
33
34
|
# collection.delete_if { |_k, v| v.blank? } # Same behavior as `Array#compact_blank!` and `Hash#compact_blank!`
|
34
|
-
# collection.
|
35
|
-
# collection.
|
35
|
+
# collection.keep_if(&:present?) # Same behavior as `Array#compact_blank!` and `Hash#compact_blank!`
|
36
|
+
# collection.keep_if { |_k, v| v.present? } # Same behavior as `Array#compact_blank!` and `Hash#compact_blank!`
|
36
37
|
#
|
37
38
|
# # good
|
38
39
|
# collection.compact_blank!
|
@@ -43,24 +44,38 @@ module RuboCop
|
|
43
44
|
extend TargetRailsVersion
|
44
45
|
|
45
46
|
MSG = 'Use `%<preferred_method>s` instead.'
|
46
|
-
RESTRICT_ON_SEND = %i[reject delete_if
|
47
|
+
RESTRICT_ON_SEND = %i[reject delete_if select keep_if].freeze
|
47
48
|
|
48
49
|
minimum_target_rails_version 6.1
|
49
50
|
|
50
51
|
def_node_matcher :reject_with_block?, <<~PATTERN
|
51
52
|
(block
|
52
|
-
(send _ {:reject :delete_if
|
53
|
+
(send _ {:reject :delete_if})
|
53
54
|
$(args ...)
|
54
55
|
(send
|
55
56
|
$(lvar _) :blank?))
|
56
57
|
PATTERN
|
57
58
|
|
58
59
|
def_node_matcher :reject_with_block_pass?, <<~PATTERN
|
59
|
-
(send _ {:reject :delete_if
|
60
|
+
(send _ {:reject :delete_if}
|
60
61
|
(block_pass
|
61
62
|
(sym :blank?)))
|
62
63
|
PATTERN
|
63
64
|
|
65
|
+
def_node_matcher :select_with_block?, <<~PATTERN
|
66
|
+
(block
|
67
|
+
(send _ {:select :keep_if})
|
68
|
+
$(args ...)
|
69
|
+
(send
|
70
|
+
$(lvar _) :present?))
|
71
|
+
PATTERN
|
72
|
+
|
73
|
+
def_node_matcher :select_with_block_pass?, <<~PATTERN
|
74
|
+
(send _ {:select :keep_if}
|
75
|
+
(block-pass
|
76
|
+
(sym :present?)))
|
77
|
+
PATTERN
|
78
|
+
|
64
79
|
def on_send(node)
|
65
80
|
return unless bad_method?(node)
|
66
81
|
|
@@ -75,8 +90,10 @@ module RuboCop
|
|
75
90
|
|
76
91
|
def bad_method?(node)
|
77
92
|
return true if reject_with_block_pass?(node)
|
93
|
+
return true if select_with_block_pass?(node)
|
78
94
|
|
79
|
-
|
95
|
+
arguments, receiver_in_block = reject_with_block?(node.parent) || select_with_block?(node.parent)
|
96
|
+
if arguments
|
80
97
|
return use_single_value_block_argument?(arguments, receiver_in_block) ||
|
81
98
|
use_hash_value_block_argument?(arguments, receiver_in_block)
|
82
99
|
end
|
@@ -103,7 +120,7 @@ module RuboCop
|
|
103
120
|
end
|
104
121
|
|
105
122
|
def preferred_method(node)
|
106
|
-
node.method?(:reject) ? 'compact_blank' : 'compact_blank!'
|
123
|
+
node.method?(:reject) || node.method?(:select) ? 'compact_blank' : 'compact_blank!'
|
107
124
|
end
|
108
125
|
end
|
109
126
|
end
|
@@ -12,10 +12,10 @@ module RuboCop
|
|
12
12
|
# The cop also reports warnings when you are using `to_time` method,
|
13
13
|
# because it doesn't know about Rails time zone either.
|
14
14
|
#
|
15
|
-
# Two styles are supported for this cop. When `EnforcedStyle` is
|
15
|
+
# Two styles are supported for this cop. When `EnforcedStyle` is `strict`
|
16
16
|
# then the Date methods `today`, `current`, `yesterday`, and `tomorrow`
|
17
17
|
# are prohibited and the usage of both `to_time`
|
18
|
-
# and
|
18
|
+
# and `to_time_in_current_zone` are reported as warning.
|
19
19
|
#
|
20
20
|
# When `EnforcedStyle` is `flexible` then only `Date.today` is prohibited.
|
21
21
|
#
|
@@ -12,6 +12,12 @@ module RuboCop
|
|
12
12
|
#
|
13
13
|
# @example
|
14
14
|
# # bad
|
15
|
+
# enum :status, [:active, :archived]
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# enum :status, { active: 0, archived: 1 }
|
19
|
+
#
|
20
|
+
# # bad
|
15
21
|
# enum status: [:active, :archived]
|
16
22
|
#
|
17
23
|
# # good
|
@@ -23,7 +29,11 @@ module RuboCop
|
|
23
29
|
MSG = 'Enum defined as an array found in `%<enum>s` enum declaration. Use hash syntax instead.'
|
24
30
|
RESTRICT_ON_SEND = %i[enum].freeze
|
25
31
|
|
26
|
-
def_node_matcher :
|
32
|
+
def_node_matcher :enum_with_array?, <<~PATTERN
|
33
|
+
(send nil? :enum $_ ${array} ...)
|
34
|
+
PATTERN
|
35
|
+
|
36
|
+
def_node_matcher :enum_with_old_syntax?, <<~PATTERN
|
27
37
|
(send nil? :enum (hash $...))
|
28
38
|
PATTERN
|
29
39
|
|
@@ -32,17 +42,19 @@ module RuboCop
|
|
32
42
|
PATTERN
|
33
43
|
|
34
44
|
def on_send(node)
|
35
|
-
|
45
|
+
target_rails_version >= 7.0 && enum_with_array?(node) do |key, array|
|
46
|
+
add_offense(array, message: message(key)) do |corrector|
|
47
|
+
corrector.replace(array, build_hash(array))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
enum_with_old_syntax?(node) do |pairs|
|
36
52
|
pairs.each do |pair|
|
37
53
|
key, array = array_pair?(pair)
|
38
54
|
next unless key
|
39
55
|
|
40
|
-
add_offense(array, message:
|
41
|
-
|
42
|
-
"#{source(elem)} => #{index}"
|
43
|
-
end.join(', ')
|
44
|
-
|
45
|
-
corrector.replace(array, "{#{hash}}")
|
56
|
+
add_offense(array, message: message(key)) do |corrector|
|
57
|
+
corrector.replace(array, build_hash(array))
|
46
58
|
end
|
47
59
|
end
|
48
60
|
end
|
@@ -50,6 +62,10 @@ module RuboCop
|
|
50
62
|
|
51
63
|
private
|
52
64
|
|
65
|
+
def message(key)
|
66
|
+
format(MSG, enum: enum_name(key))
|
67
|
+
end
|
68
|
+
|
53
69
|
def enum_name(key)
|
54
70
|
case key.type
|
55
71
|
when :sym, :str
|
@@ -69,6 +85,13 @@ module RuboCop
|
|
69
85
|
elem.source
|
70
86
|
end
|
71
87
|
end
|
88
|
+
|
89
|
+
def build_hash(array)
|
90
|
+
hash = array.children.each_with_index.map do |elem, index|
|
91
|
+
"#{source(elem)} => #{index}"
|
92
|
+
end.join(', ')
|
93
|
+
"{#{hash}}"
|
94
|
+
end
|
72
95
|
end
|
73
96
|
end
|
74
97
|
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Rails
|
6
|
+
# Looks for enums written with keyword arguments syntax.
|
7
|
+
#
|
8
|
+
# Defining enums with keyword arguments syntax is deprecated and will be removed in Rails 8.0.
|
9
|
+
# Positional arguments should be used instead:
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# # bad
|
13
|
+
# enum status: { active: 0, archived: 1 }, _prefix: true
|
14
|
+
#
|
15
|
+
# # good
|
16
|
+
# enum :status, { active: 0, archived: 1 }, prefix: true
|
17
|
+
#
|
18
|
+
class EnumSyntax < Base
|
19
|
+
extend AutoCorrector
|
20
|
+
extend TargetRailsVersion
|
21
|
+
|
22
|
+
minimum_target_rails_version 7.0
|
23
|
+
|
24
|
+
MSG = 'Enum defined with keyword arguments in `%<enum>s` enum declaration. Use positional arguments instead.'
|
25
|
+
MSG_OPTIONS = 'Enum defined with deprecated options in `%<enum>s` enum declaration. Remove the `_` prefix.'
|
26
|
+
RESTRICT_ON_SEND = %i[enum].freeze
|
27
|
+
|
28
|
+
# From https://github.com/rails/rails/blob/v7.2.1/activerecord/lib/active_record/enum.rb#L231
|
29
|
+
OPTION_NAMES = %w[prefix suffix scopes default instance_methods].freeze
|
30
|
+
UNDERSCORED_OPTION_NAMES = OPTION_NAMES.map { |option| "_#{option}" }.freeze
|
31
|
+
|
32
|
+
def_node_matcher :enum?, <<~PATTERN
|
33
|
+
(send nil? :enum (hash $...))
|
34
|
+
PATTERN
|
35
|
+
|
36
|
+
def_node_matcher :enum_with_options?, <<~PATTERN
|
37
|
+
(send nil? :enum $_ ${array hash} $_)
|
38
|
+
PATTERN
|
39
|
+
|
40
|
+
def on_send(node)
|
41
|
+
check_and_correct_keyword_args(node)
|
42
|
+
check_enum_options(node)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def check_and_correct_keyword_args(node)
|
48
|
+
enum?(node) do |pairs|
|
49
|
+
pairs.each do |pair|
|
50
|
+
next if option_key?(pair)
|
51
|
+
|
52
|
+
correct_keyword_args(node, pair.key, pair.value, pairs[1..])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def check_enum_options(node)
|
58
|
+
enum_with_options?(node) do |key, _, options|
|
59
|
+
options.children.each do |option|
|
60
|
+
next unless option_key?(option)
|
61
|
+
|
62
|
+
add_offense(option.key, message: format(MSG_OPTIONS, enum: enum_name_value(key))) do |corrector|
|
63
|
+
corrector.replace(option.key, option.key.source.delete_prefix('_'))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def correct_keyword_args(node, key, values, options)
|
70
|
+
add_offense(values, message: format(MSG, enum: enum_name_value(key))) do |corrector|
|
71
|
+
# TODO: Multi-line autocorrect could be implemented in the future.
|
72
|
+
next if multiple_enum_definitions?(node)
|
73
|
+
|
74
|
+
preferred_syntax = "enum #{enum_name(key)}, #{values.source}#{correct_options(options)}"
|
75
|
+
|
76
|
+
corrector.replace(node, preferred_syntax)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def multiple_enum_definitions?(node)
|
81
|
+
keys = node.first_argument.keys.map { |key| key.source.delete_prefix('_') }
|
82
|
+
filterred_keys = keys.filter { |key| !OPTION_NAMES.include?(key) }
|
83
|
+
filterred_keys.size >= 2
|
84
|
+
end
|
85
|
+
|
86
|
+
def enum_name_value(key)
|
87
|
+
case key.type
|
88
|
+
when :sym, :str
|
89
|
+
key.value
|
90
|
+
else
|
91
|
+
key.source
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def enum_name(elem)
|
96
|
+
case elem.type
|
97
|
+
when :str
|
98
|
+
elem.value.dump
|
99
|
+
when :sym
|
100
|
+
elem.value.inspect
|
101
|
+
else
|
102
|
+
elem.source
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def option_key?(pair)
|
107
|
+
UNDERSCORED_OPTION_NAMES.include?(pair.key.source)
|
108
|
+
end
|
109
|
+
|
110
|
+
def correct_options(options)
|
111
|
+
corrected_options = options.map do |pair|
|
112
|
+
name = if pair.key.source[0] == '_'
|
113
|
+
pair.key.source[1..]
|
114
|
+
else
|
115
|
+
pair.key.source
|
116
|
+
end
|
117
|
+
|
118
|
+
"#{name}: #{pair.value.source}"
|
119
|
+
end.join(', ')
|
120
|
+
|
121
|
+
", #{corrected_options}" unless corrected_options.empty?
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -7,6 +7,18 @@ module RuboCop
|
|
7
7
|
#
|
8
8
|
# @example
|
9
9
|
# # bad
|
10
|
+
# enum :status, { active: 0, archived: 0 }
|
11
|
+
#
|
12
|
+
# # good
|
13
|
+
# enum :status, { active: 0, archived: 1 }
|
14
|
+
#
|
15
|
+
# # bad
|
16
|
+
# enum :status, [:active, :archived, :active]
|
17
|
+
#
|
18
|
+
# # good
|
19
|
+
# enum :status, [:active, :archived]
|
20
|
+
#
|
21
|
+
# # bad
|
10
22
|
# enum status: { active: 0, archived: 0 }
|
11
23
|
#
|
12
24
|
# # good
|
@@ -24,6 +36,10 @@ module RuboCop
|
|
24
36
|
RESTRICT_ON_SEND = %i[enum].freeze
|
25
37
|
|
26
38
|
def_node_matcher :enum?, <<~PATTERN
|
39
|
+
(send nil? :enum $_ ${array hash} ...)
|
40
|
+
PATTERN
|
41
|
+
|
42
|
+
def_node_matcher :enum_with_old_syntax?, <<~PATTERN
|
27
43
|
(send nil? :enum (hash $...))
|
28
44
|
PATTERN
|
29
45
|
|
@@ -32,15 +48,17 @@ module RuboCop
|
|
32
48
|
PATTERN
|
33
49
|
|
34
50
|
def on_send(node)
|
35
|
-
enum?(node) do |
|
51
|
+
enum?(node) do |key, args|
|
52
|
+
consecutive_duplicates(args.values).each do |item|
|
53
|
+
add_offense(item, message: message(key, item))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
enum_with_old_syntax?(node) do |pairs|
|
36
58
|
pairs.each do |pair|
|
37
59
|
enum_values(pair) do |key, args|
|
38
|
-
|
39
|
-
|
40
|
-
next unless duplicates?(items)
|
41
|
-
|
42
|
-
consecutive_duplicates(items).each do |item|
|
43
|
-
add_offense(item, message: format(MSG, value: item.source, enum: enum_name(key)))
|
60
|
+
consecutive_duplicates(args.values).each do |item|
|
61
|
+
add_offense(item, message: message(key, item))
|
44
62
|
end
|
45
63
|
end
|
46
64
|
end
|
@@ -57,6 +75,10 @@ module RuboCop
|
|
57
75
|
key.source
|
58
76
|
end
|
59
77
|
end
|
78
|
+
|
79
|
+
def message(key, item)
|
80
|
+
format(MSG, value: item.source, enum: enum_name(key))
|
81
|
+
end
|
60
82
|
end
|
61
83
|
end
|
62
84
|
end
|
@@ -7,17 +7,26 @@ module RuboCop
|
|
7
7
|
# and can be replaced with `select`.
|
8
8
|
#
|
9
9
|
# Since `pluck` is an eager method and hits the database immediately,
|
10
|
-
# using `select` helps to avoid additional database queries
|
10
|
+
# using `select` helps to avoid additional database queries by running as
|
11
|
+
# a subquery.
|
11
12
|
#
|
12
|
-
# This cop has two
|
13
|
-
#
|
14
|
-
# (
|
13
|
+
# This cop has two modes of enforcement. When the `EnforcedStyle` is set
|
14
|
+
# to `conservative` (the default), only calls to `pluck` on a constant
|
15
|
+
# (e.g. a model class) within `where` are considered offenses.
|
15
16
|
#
|
16
17
|
# @safety
|
17
|
-
# When
|
18
|
-
# `where`
|
19
|
-
#
|
20
|
-
# `ActiveRecord::Relation` instance
|
18
|
+
# When `EnforcedStyle` is set to `aggressive`, all calls to `pluck`
|
19
|
+
# within `where` are considered offenses. This might lead to false
|
20
|
+
# positives because the check cannot distinguish between calls to
|
21
|
+
# `pluck` on an `ActiveRecord::Relation` instance and calls to `pluck`
|
22
|
+
# on an `Array` instance.
|
23
|
+
#
|
24
|
+
# Additionally, when using a subquery with the SQL `IN` operator,
|
25
|
+
# databases like PostgreSQL and MySQL can't optimize complex queries as
|
26
|
+
# well. They need to scan all records of the outer table against the
|
27
|
+
# subquery result sequentially, rather than using an index. This can
|
28
|
+
# cause significant performance issues compared to writing the query
|
29
|
+
# differently or using `pluck`.
|
21
30
|
#
|
22
31
|
# @example
|
23
32
|
# # bad
|
@@ -10,25 +10,39 @@ module RuboCop
|
|
10
10
|
# # bad
|
11
11
|
# 3.day.ago
|
12
12
|
# 1.months.ago
|
13
|
+
# 5.megabyte
|
14
|
+
# 1.gigabytes
|
13
15
|
#
|
14
16
|
# # good
|
15
17
|
# 3.days.ago
|
16
18
|
# 1.month.ago
|
19
|
+
# 5.megabytes
|
20
|
+
# 1.gigabyte
|
17
21
|
class PluralizationGrammar < Base
|
18
22
|
extend AutoCorrector
|
19
23
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
24
|
+
SINGULAR_METHODS = {
|
25
|
+
second: :seconds,
|
26
|
+
minute: :minutes,
|
27
|
+
hour: :hours,
|
28
|
+
day: :days,
|
29
|
+
week: :weeks,
|
30
|
+
fortnight: :fortnights,
|
31
|
+
month: :months,
|
32
|
+
year: :years,
|
33
|
+
byte: :bytes,
|
34
|
+
kilobyte: :kilobytes,
|
35
|
+
megabyte: :megabytes,
|
36
|
+
gigabyte: :gigabytes,
|
37
|
+
terabyte: :terabytes,
|
38
|
+
petabyte: :petabytes,
|
39
|
+
exabyte: :exabytes,
|
40
|
+
zettabyte: :zettabytes
|
41
|
+
}.freeze
|
42
|
+
|
43
|
+
RESTRICT_ON_SEND = SINGULAR_METHODS.keys + SINGULAR_METHODS.values
|
44
|
+
|
45
|
+
PLURAL_METHODS = SINGULAR_METHODS.invert.freeze
|
32
46
|
|
33
47
|
MSG = 'Prefer `%<number>s.%<correct>s`.'
|
34
48
|
|
@@ -86,15 +100,15 @@ module RuboCop
|
|
86
100
|
end
|
87
101
|
|
88
102
|
def pluralize(method_name)
|
89
|
-
|
103
|
+
SINGULAR_METHODS.fetch(method_name.to_sym).to_s
|
90
104
|
end
|
91
105
|
|
92
106
|
def singularize(method_name)
|
93
|
-
|
107
|
+
PLURAL_METHODS.fetch(method_name.to_sym).to_s
|
94
108
|
end
|
95
109
|
|
96
110
|
def duration_method?(method_name)
|
97
|
-
|
111
|
+
SINGULAR_METHODS.key?(method_name) || PLURAL_METHODS.key?(method_name)
|
98
112
|
end
|
99
113
|
end
|
100
114
|
end
|
@@ -3,35 +3,6 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Rails
|
6
|
-
# TODO: In the future, please support only RuboCop 1.52+ and use `RuboCop::Cop::AllowedReceivers`:
|
7
|
-
# https://github.com/rubocop/rubocop/blob/v1.52.0/lib/rubocop/cop/mixin/allowed_receivers.rb
|
8
|
-
# At that time, this duplicated module implementation can be removed.
|
9
|
-
module AllowedReceivers
|
10
|
-
def allowed_receiver?(receiver)
|
11
|
-
receiver_name = receiver_name(receiver)
|
12
|
-
|
13
|
-
allowed_receivers.include?(receiver_name)
|
14
|
-
end
|
15
|
-
|
16
|
-
def receiver_name(receiver)
|
17
|
-
return receiver_name(receiver.receiver) if receiver.receiver && !receiver.receiver.const_type?
|
18
|
-
|
19
|
-
if receiver.send_type?
|
20
|
-
if receiver.receiver
|
21
|
-
"#{receiver_name(receiver.receiver)}.#{receiver.method_name}"
|
22
|
-
else
|
23
|
-
receiver.method_name.to_s
|
24
|
-
end
|
25
|
-
else
|
26
|
-
receiver.source
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def allowed_receivers
|
31
|
-
cop_config.fetch('AllowedReceivers', [])
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
6
|
# Detect redundant `all` used as a receiver for Active Record query methods.
|
36
7
|
#
|
37
8
|
# For the methods `delete_all` and `destroy_all`, this cop will only check cases where the receiver is a model.
|
@@ -39,6 +39,9 @@ module RuboCop
|
|
39
39
|
MSG = 'Remove explicit presence validation for %<association>s.'
|
40
40
|
RESTRICT_ON_SEND = %i[validates].freeze
|
41
41
|
|
42
|
+
# From https://github.com/rails/rails/blob/7a0bf93b9dd291c7f61121a41b3a813ac8857e6a/activemodel/lib/active_model/validations/validates.rb#L157-L159
|
43
|
+
NON_VALIDATION_OPTIONS = %i[if unless on allow_blank allow_nil strict].freeze
|
44
|
+
|
42
45
|
minimum_target_rails_version 5.0
|
43
46
|
|
44
47
|
# @!method presence_validation?(node)
|
@@ -170,6 +173,12 @@ module RuboCop
|
|
170
173
|
|
171
174
|
def on_send(node)
|
172
175
|
presence_validation?(node) do |all_keys, options, presence|
|
176
|
+
# If presence is the only validation option and other non-validation options
|
177
|
+
# are present, removing it will cause rails to error.
|
178
|
+
used_option_keys = options.keys.select(&:sym_type?).map(&:value)
|
179
|
+
remaining_validations = used_option_keys - NON_VALIDATION_OPTIONS - [:presence]
|
180
|
+
return if remaining_validations.none? && options.keys.length > 1
|
181
|
+
|
173
182
|
keys = non_optional_belongs_to(node.parent, all_keys)
|
174
183
|
return if keys.none?
|
175
184
|
|
@@ -53,9 +53,12 @@ module RuboCop
|
|
53
53
|
node.pairs.find { |p| p.key.value.to_sym == :content_type }
|
54
54
|
end
|
55
55
|
|
56
|
-
def compatible_content_type?(
|
57
|
-
|
58
|
-
|
56
|
+
def compatible_content_type?(pair_node)
|
57
|
+
if pair_node.nil?
|
58
|
+
!cop_config['ContentTypeCompatibility']
|
59
|
+
elsif pair_node.value.respond_to?(:value)
|
60
|
+
pair_node.value.value == 'text/plain'
|
61
|
+
end
|
59
62
|
end
|
60
63
|
|
61
64
|
def replacement(rest_options, option_value)
|
@@ -23,6 +23,8 @@ module RuboCop
|
|
23
23
|
# File.binread(Rails.root.join('db', 'schema.rb'))
|
24
24
|
# File.write(Rails.root.join('db', 'schema.rb'), content)
|
25
25
|
# File.binwrite(Rails.root.join('db', 'schema.rb'), content)
|
26
|
+
# Dir.glob(Rails.root.join('db', 'schema.rb'))
|
27
|
+
# Dir[Rails.root.join('db', 'schema.rb')]
|
26
28
|
#
|
27
29
|
# # good
|
28
30
|
# Rails.root.join('db', 'schema.rb').open
|
@@ -31,14 +33,15 @@ module RuboCop
|
|
31
33
|
# Rails.root.join('db', 'schema.rb').binread
|
32
34
|
# Rails.root.join('db', 'schema.rb').write(content)
|
33
35
|
# Rails.root.join('db', 'schema.rb').binwrite(content)
|
36
|
+
# Rails.root.glob("db/schema.rb")
|
34
37
|
#
|
35
38
|
class RootPathnameMethods < Base # rubocop:disable Metrics/ClassLength
|
36
39
|
extend AutoCorrector
|
37
40
|
include RangeHelp
|
38
41
|
|
39
|
-
MSG = '`%<rails_root>s` is a `Pathname
|
42
|
+
MSG = '`%<rails_root>s` is a `Pathname`, so you can use `%<replacement>s`.'
|
40
43
|
|
41
|
-
DIR_GLOB_METHODS = %i[glob].to_set.freeze
|
44
|
+
DIR_GLOB_METHODS = %i[[] glob].to_set.freeze
|
42
45
|
|
43
46
|
DIR_NON_GLOB_METHODS = %i[
|
44
47
|
children
|
@@ -171,7 +174,7 @@ module RuboCop
|
|
171
174
|
|
172
175
|
def_node_matcher :dir_glob?, <<~PATTERN
|
173
176
|
(send
|
174
|
-
(const {cbase nil?} :Dir)
|
177
|
+
(const {cbase nil?} :Dir) DIR_GLOB_METHODS ...)
|
175
178
|
PATTERN
|
176
179
|
|
177
180
|
def_node_matcher :rails_root_pathname?, <<~PATTERN
|
@@ -188,13 +191,14 @@ module RuboCop
|
|
188
191
|
|
189
192
|
def on_send(node)
|
190
193
|
evidence(node) do |method, path, args, rails_root|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
end
|
194
|
+
replacement = if dir_glob?(node)
|
195
|
+
build_path_glob_replacement(path)
|
196
|
+
else
|
197
|
+
build_path_replacement(path, method, args)
|
198
|
+
end
|
197
199
|
|
200
|
+
message = format(MSG, rails_root: rails_root.source, replacement: replacement)
|
201
|
+
add_offense(node, message: message) do |corrector|
|
198
202
|
corrector.replace(node, replacement)
|
199
203
|
end
|
200
204
|
end
|
@@ -217,12 +221,12 @@ module RuboCop
|
|
217
221
|
end
|
218
222
|
end
|
219
223
|
|
220
|
-
def build_path_glob_replacement(path
|
224
|
+
def build_path_glob_replacement(path)
|
221
225
|
receiver = range_between(path.source_range.begin_pos, path.children.first.loc.selector.end_pos).source
|
222
226
|
|
223
227
|
argument = path.arguments.one? ? path.first_argument.source : join_arguments(path.arguments)
|
224
228
|
|
225
|
-
"#{receiver}
|
229
|
+
"#{receiver}.glob(#{argument})"
|
226
230
|
end
|
227
231
|
|
228
232
|
def build_path_replacement(path, method, args)
|
@@ -100,7 +100,8 @@ module RuboCop
|
|
100
100
|
end
|
101
101
|
|
102
102
|
def forbidden_methods
|
103
|
-
|
103
|
+
# TODO: Remove when RuboCop Rails 3 releases.
|
104
|
+
obsolete_result = cop_config['Blacklist'] # rubocop:disable InternalAffairs/UndefinedConfig
|
104
105
|
if obsolete_result
|
105
106
|
warn '`Blacklist` has been renamed to `ForbiddenMethods`.' unless @displayed_forbidden_warning
|
106
107
|
@displayed_forbidden_warning = true
|
@@ -111,7 +112,8 @@ module RuboCop
|
|
111
112
|
end
|
112
113
|
|
113
114
|
def allowed_methods
|
114
|
-
|
115
|
+
# TODO: Remove when RuboCop Rails 3 releases.
|
116
|
+
obsolete_result = cop_config['Whitelist'] # rubocop:disable InternalAffairs/UndefinedConfig
|
115
117
|
if obsolete_result
|
116
118
|
warn '`Whitelist` has been renamed to `AllowedMethods`.' unless @displayed_allowed_warning
|
117
119
|
@displayed_allowed_warning = true
|
@@ -59,11 +59,11 @@ module RuboCop
|
|
59
59
|
|
60
60
|
def on_send(node)
|
61
61
|
return if node.receiver
|
62
|
+
return unless (last_argument = node.last_argument)
|
62
63
|
|
63
64
|
range = node.loc.selector
|
64
65
|
|
65
66
|
add_offense(range, message: message(node)) do |corrector|
|
66
|
-
last_argument = node.last_argument
|
67
67
|
return if !last_argument.literal? && !last_argument.splat_type? && !frozen_array_argument?(last_argument)
|
68
68
|
|
69
69
|
corrector.replace(range, 'validates')
|
@@ -4,7 +4,8 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Rails
|
6
6
|
# Identifies places where manually constructed SQL
|
7
|
-
# in `where` can be replaced with
|
7
|
+
# in `where` and `where.not` can be replaced with
|
8
|
+
# `where(attribute: value)` and `where.not(attribute: value)`.
|
8
9
|
#
|
9
10
|
# @safety
|
10
11
|
# This cop's autocorrection is unsafe because is may change SQL.
|
@@ -13,6 +14,7 @@ module RuboCop
|
|
13
14
|
# @example
|
14
15
|
# # bad
|
15
16
|
# User.where('name = ?', 'Gabe')
|
17
|
+
# User.where.not('name = ?', 'Gabe')
|
16
18
|
# User.where('name = :name', name: 'Gabe')
|
17
19
|
# User.where('name IS NULL')
|
18
20
|
# User.where('name IN (?)', ['john', 'jane'])
|
@@ -21,6 +23,7 @@ module RuboCop
|
|
21
23
|
#
|
22
24
|
# # good
|
23
25
|
# User.where(name: 'Gabe')
|
26
|
+
# User.where.not(name: 'Gabe')
|
24
27
|
# User.where(name: nil)
|
25
28
|
# User.where(name: ['john', 'jane'])
|
26
29
|
# User.where(users: { name: 'Gabe' })
|
@@ -29,25 +32,27 @@ module RuboCop
|
|
29
32
|
extend AutoCorrector
|
30
33
|
|
31
34
|
MSG = 'Use `%<good_method>s` instead of manually constructing SQL.'
|
32
|
-
RESTRICT_ON_SEND = %i[where].freeze
|
35
|
+
RESTRICT_ON_SEND = %i[where not].freeze
|
33
36
|
|
34
37
|
def_node_matcher :where_method_call?, <<~PATTERN
|
35
38
|
{
|
36
|
-
(call _ :where (array $str_type? $_ ?))
|
37
|
-
(call _ :where $str_type? $_ ?)
|
39
|
+
(call _ {:where :not} (array $str_type? $_ ?))
|
40
|
+
(call _ {:where :not} $str_type? $_ ?)
|
38
41
|
}
|
39
42
|
PATTERN
|
40
43
|
|
41
44
|
def on_send(node)
|
45
|
+
return if node.method?(:not) && !where_not?(node)
|
46
|
+
|
42
47
|
where_method_call?(node) do |template_node, value_node|
|
43
48
|
value_node = value_node.first
|
44
49
|
|
45
50
|
range = offense_range(node)
|
46
51
|
|
47
|
-
|
48
|
-
return unless
|
52
|
+
column, value = extract_column_and_value(template_node, value_node)
|
53
|
+
return unless value
|
49
54
|
|
50
|
-
good_method = build_good_method(
|
55
|
+
good_method = build_good_method(node.method_name, column, value)
|
51
56
|
message = format(MSG, good_method: good_method)
|
52
57
|
|
53
58
|
add_offense(range, message: message) do |corrector|
|
@@ -69,11 +74,12 @@ module RuboCop
|
|
69
74
|
range_between(node.loc.selector.begin_pos, node.source_range.end_pos)
|
70
75
|
end
|
71
76
|
|
77
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
72
78
|
def extract_column_and_value(template_node, value_node)
|
73
79
|
value =
|
74
80
|
case template_node.value
|
75
81
|
when EQ_ANONYMOUS_RE, IN_ANONYMOUS_RE
|
76
|
-
value_node
|
82
|
+
value_node&.source
|
77
83
|
when EQ_NAMED_RE, IN_NAMED_RE
|
78
84
|
return unless value_node&.hash_type?
|
79
85
|
|
@@ -85,18 +91,28 @@ module RuboCop
|
|
85
91
|
return
|
86
92
|
end
|
87
93
|
|
88
|
-
|
94
|
+
column_qualifier = Regexp.last_match(1)
|
95
|
+
return if column_qualifier.count('.') > 1
|
96
|
+
|
97
|
+
[column_qualifier, value]
|
89
98
|
end
|
99
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
90
100
|
|
91
|
-
def build_good_method(column, value)
|
101
|
+
def build_good_method(method_name, column, value)
|
92
102
|
if column.include?('.')
|
93
103
|
table, column = column.split('.')
|
94
104
|
|
95
|
-
"
|
105
|
+
"#{method_name}(#{table}: { #{column}: #{value} })"
|
96
106
|
else
|
97
|
-
"
|
107
|
+
"#{method_name}(#{column}: #{value})"
|
98
108
|
end
|
99
109
|
end
|
110
|
+
|
111
|
+
def where_not?(node)
|
112
|
+
return false unless (receiver = node.receiver)
|
113
|
+
|
114
|
+
receiver.send_type? && receiver.method?(:where)
|
115
|
+
end
|
100
116
|
end
|
101
117
|
end
|
102
118
|
end
|
@@ -43,10 +43,10 @@ module RuboCop
|
|
43
43
|
|
44
44
|
range = offense_range(node)
|
45
45
|
|
46
|
-
|
47
|
-
return unless
|
46
|
+
column, value = extract_column_and_value(template_node, value_node)
|
47
|
+
return unless value
|
48
48
|
|
49
|
-
good_method = build_good_method(node.loc.dot&.source,
|
49
|
+
good_method = build_good_method(node.loc.dot&.source, column, value)
|
50
50
|
message = format(MSG, good_method: good_method)
|
51
51
|
|
52
52
|
add_offense(range, message: message) do |corrector|
|
@@ -68,13 +68,14 @@ module RuboCop
|
|
68
68
|
range_between(node.loc.selector.begin_pos, node.source_range.end_pos)
|
69
69
|
end
|
70
70
|
|
71
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
71
72
|
def extract_column_and_value(template_node, value_node)
|
72
73
|
value =
|
73
74
|
case template_node.value
|
74
75
|
when NOT_EQ_ANONYMOUS_RE, NOT_IN_ANONYMOUS_RE
|
75
|
-
value_node
|
76
|
+
value_node&.source
|
76
77
|
when NOT_EQ_NAMED_RE, NOT_IN_NAMED_RE
|
77
|
-
return unless value_node
|
78
|
+
return unless value_node&.hash_type?
|
78
79
|
|
79
80
|
pair = value_node.pairs.find { |p| p.key.value.to_sym == Regexp.last_match(2).to_sym }
|
80
81
|
pair.value.source
|
@@ -84,8 +85,12 @@ module RuboCop
|
|
84
85
|
return
|
85
86
|
end
|
86
87
|
|
87
|
-
|
88
|
+
column_qualifier = Regexp.last_match(1)
|
89
|
+
return if column_qualifier.count('.') > 1
|
90
|
+
|
91
|
+
[column_qualifier, value]
|
88
92
|
end
|
93
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
89
94
|
|
90
95
|
def build_good_method(dot, column, value)
|
91
96
|
dot ||= '.'
|
@@ -140,6 +140,8 @@ module RuboCop
|
|
140
140
|
rhs = pair2.value
|
141
141
|
end
|
142
142
|
end
|
143
|
+
else
|
144
|
+
return
|
143
145
|
end
|
144
146
|
|
145
147
|
if lhs
|
@@ -150,7 +152,10 @@ module RuboCop
|
|
150
152
|
rhs_source = parentheses_needed?(rhs) ? "(#{rhs.source})" : rhs.source
|
151
153
|
end
|
152
154
|
|
153
|
-
|
155
|
+
column_qualifier = Regexp.last_match(1)
|
156
|
+
return if column_qualifier.count('.') > 1
|
157
|
+
|
158
|
+
[column_qualifier, "#{lhs_source}#{operator}#{rhs_source}"] if operator
|
154
159
|
end
|
155
160
|
# rubocop:enable Metrics
|
156
161
|
|
@@ -46,6 +46,7 @@ require_relative 'rails/duration_arithmetic'
|
|
46
46
|
require_relative 'rails/dynamic_find_by'
|
47
47
|
require_relative 'rails/eager_evaluation_log_message'
|
48
48
|
require_relative 'rails/enum_hash'
|
49
|
+
require_relative 'rails/enum_syntax'
|
49
50
|
require_relative 'rails/enum_uniqueness'
|
50
51
|
require_relative 'rails/env_local'
|
51
52
|
require_relative 'rails/environment_comparison'
|
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.26.1
|
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: 2024-
|
13
|
+
date: 2024-09-07 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
@@ -46,7 +46,7 @@ dependencies:
|
|
46
46
|
requirements:
|
47
47
|
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: 1.
|
49
|
+
version: 1.52.0
|
50
50
|
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
52
|
version: '2.0'
|
@@ -56,7 +56,7 @@ dependencies:
|
|
56
56
|
requirements:
|
57
57
|
- - ">="
|
58
58
|
- !ruby/object:Gem::Version
|
59
|
-
version: 1.
|
59
|
+
version: 1.52.0
|
60
60
|
- - "<"
|
61
61
|
- !ruby/object:Gem::Version
|
62
62
|
version: '2.0'
|
@@ -140,6 +140,7 @@ files:
|
|
140
140
|
- lib/rubocop/cop/rails/dynamic_find_by.rb
|
141
141
|
- lib/rubocop/cop/rails/eager_evaluation_log_message.rb
|
142
142
|
- lib/rubocop/cop/rails/enum_hash.rb
|
143
|
+
- lib/rubocop/cop/rails/enum_syntax.rb
|
143
144
|
- lib/rubocop/cop/rails/enum_uniqueness.rb
|
144
145
|
- lib/rubocop/cop/rails/env_local.rb
|
145
146
|
- lib/rubocop/cop/rails/environment_comparison.rb
|
@@ -246,7 +247,7 @@ metadata:
|
|
246
247
|
homepage_uri: https://docs.rubocop.org/rubocop-rails/
|
247
248
|
changelog_uri: https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md
|
248
249
|
source_code_uri: https://github.com/rubocop/rubocop-rails/
|
249
|
-
documentation_uri: https://docs.rubocop.org/rubocop-rails/2.
|
250
|
+
documentation_uri: https://docs.rubocop.org/rubocop-rails/2.26/
|
250
251
|
bug_tracker_uri: https://github.com/rubocop/rubocop-rails/issues
|
251
252
|
rubygems_mfa_required: 'true'
|
252
253
|
post_install_message:
|