rubocop-rails 2.23.1 → 2.26.2
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/README.md +16 -2
- data/config/default.yml +32 -7
- data/lib/rubocop/cop/mixin/active_record_helper.rb +6 -1
- data/lib/rubocop/cop/mixin/target_rails_version.rb +29 -2
- data/lib/rubocop/cop/rails/action_controller_flash_before_render.rb +2 -0
- 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/active_support_on_load.rb +21 -1
- data/lib/rubocop/cop/rails/application_record.rb +4 -0
- data/lib/rubocop/cop/rails/bulk_change_table.rb +10 -4
- data/lib/rubocop/cop/rails/compact_blank.rb +29 -8
- data/lib/rubocop/cop/rails/dangerous_column_names.rb +1 -2
- 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 +128 -0
- data/lib/rubocop/cop/rails/enum_uniqueness.rb +29 -7
- data/lib/rubocop/cop/rails/expanded_date_range.rb +1 -1
- data/lib/rubocop/cop/rails/file_path.rb +1 -1
- data/lib/rubocop/cop/rails/find_by.rb +1 -1
- data/lib/rubocop/cop/rails/http_status.rb +12 -2
- data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +1 -1
- data/lib/rubocop/cop/rails/link_to_blank.rb +2 -2
- data/lib/rubocop/cop/rails/not_null_column.rb +93 -13
- data/lib/rubocop/cop/rails/pick.rb +4 -0
- 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_foreign_key.rb +1 -1
- data/lib/rubocop/cop/rails/redundant_presence_validation_on_belongs_to.rb +9 -0
- data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +1 -1
- data/lib/rubocop/cop/rails/reflection_class_name.rb +1 -1
- data/lib/rubocop/cop/rails/render_plain_text.rb +6 -3
- data/lib/rubocop/cop/rails/request_referer.rb +1 -1
- data/lib/rubocop/cop/rails/reversible_migration.rb +1 -1
- data/lib/rubocop/cop/rails/root_pathname_methods.rb +15 -11
- data/lib/rubocop/cop/rails/save_bang.rb +2 -0
- data/lib/rubocop/cop/rails/skips_model_validations.rb +8 -3
- data/lib/rubocop/cop/rails/time_zone.rb +2 -1
- data/lib/rubocop/cop/rails/uniq_before_pluck.rb +12 -4
- data/lib/rubocop/cop/rails/unknown_env.rb +1 -1
- data/lib/rubocop/cop/rails/unused_ignored_columns.rb +6 -0
- data/lib/rubocop/cop/rails/validation.rb +8 -3
- data/lib/rubocop/cop/rails/where_equals.rb +28 -12
- data/lib/rubocop/cop/rails/where_exists.rb +3 -3
- data/lib/rubocop/cop/rails/where_missing.rb +5 -1
- data/lib/rubocop/cop/rails/where_not.rb +11 -6
- data/lib/rubocop/cop/rails/where_range.rb +203 -0
- data/lib/rubocop/cop/rails_cops.rb +2 -0
- data/lib/rubocop/rails/schema_loader/schema.rb +2 -1
- data/lib/rubocop/rails/schema_loader.rb +5 -15
- data/lib/rubocop/rails/version.rb +1 -1
- metadata +10 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c6d480f2ef30bba709b183d1a3b71dee6c0838ea2815975b5fd25ab5933277ad
|
|
4
|
+
data.tar.gz: 1d36f2779e44e1fa03437154f388bf2e865c3af810e0238f5ddc6580f024fd04
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5cc2521c185293872667eb2a23aaaadc4ddee8289b1f16c9fff1e6c87b9498708226a0147697acb9bcc3be69642c3f3ecc063b749056c0df1cdb065a224e4a3d
|
|
7
|
+
data.tar.gz: ea268a009b987a6f61008602d67a8e89659611b7469fe6c1b9c81825b5f9227391035866b2ec593e6109e91a470d607f6f4bb48fd11155b9177d59daf2301111
|
data/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# RuboCop Rails
|
|
2
2
|
|
|
3
3
|
[](https://badge.fury.io/rb/rubocop-rails)
|
|
4
|
-
[](https://github.com/rubocop/rubocop-rails/actions/workflows/test.yml)
|
|
5
5
|
|
|
6
6
|
A [RuboCop](https://github.com/rubocop/rubocop) extension focused on enforcing Rails best practices and coding conventions.
|
|
7
7
|
|
|
@@ -65,7 +65,7 @@ end
|
|
|
65
65
|
|
|
66
66
|
## Rails configuration tip
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
In Rails 6.1+, add the following `config.generators.after_generate` setting to
|
|
69
69
|
your `config/environments/development.rb` to apply RuboCop autocorrection to code generated by `bin/rails g`.
|
|
70
70
|
|
|
71
71
|
```ruby
|
|
@@ -84,6 +84,20 @@ It uses `rubocop -A` to apply `Style/FrozenStringLiteralComment` and other unsaf
|
|
|
84
84
|
`rubocop -A` is unsafe autocorrection, but code generated by default is simple and less likely to
|
|
85
85
|
be incompatible with `rubocop -A`. If you have problems you can replace it with `rubocop -a` instead.
|
|
86
86
|
|
|
87
|
+
In Rails 7.2+, it is recommended to use `config.generators.apply_rubocop_autocorrect_after_generate!` instead of the above setting:
|
|
88
|
+
|
|
89
|
+
```diff
|
|
90
|
+
# config/environments/development.rb
|
|
91
|
+
Rails.application.configure do
|
|
92
|
+
(snip)
|
|
93
|
+
# Apply autocorrection by RuboCop to files generated by `bin/rails generate`.
|
|
94
|
+
- # config.generators.apply_rubocop_autocorrect_after_generate!
|
|
95
|
+
+ config.generators.apply_rubocop_autocorrect_after_generate!
|
|
96
|
+
end
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
You only need to uncomment.
|
|
100
|
+
|
|
87
101
|
## The Cops
|
|
88
102
|
|
|
89
103
|
All cops are located under
|
data/config/default.yml
CHANGED
|
@@ -165,6 +165,7 @@ Rails/ActiveSupportOnLoad:
|
|
|
165
165
|
- 'https://guides.rubyonrails.org/engines.html#available-load-hooks'
|
|
166
166
|
SafeAutoCorrect: false
|
|
167
167
|
VersionAdded: '2.16'
|
|
168
|
+
VersionChanged: '2.24'
|
|
168
169
|
|
|
169
170
|
Rails/AddColumnIndex:
|
|
170
171
|
Description: >-
|
|
@@ -211,7 +212,9 @@ Rails/ApplicationRecord:
|
|
|
211
212
|
Enabled: true
|
|
212
213
|
SafeAutoCorrect: false
|
|
213
214
|
VersionAdded: '0.49'
|
|
214
|
-
VersionChanged: '2.
|
|
215
|
+
VersionChanged: '2.26'
|
|
216
|
+
Exclude:
|
|
217
|
+
- db/**/*.rb
|
|
215
218
|
|
|
216
219
|
Rails/ArelStar:
|
|
217
220
|
Description: 'Enforces `Arel.star` instead of `"*"` for expanded columns.'
|
|
@@ -423,6 +426,14 @@ Rails/EnumHash:
|
|
|
423
426
|
Include:
|
|
424
427
|
- app/models/**/*.rb
|
|
425
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
|
+
|
|
426
437
|
Rails/EnumUniqueness:
|
|
427
438
|
Description: 'Avoid duplicate integers in hash-syntax `enum` declaration.'
|
|
428
439
|
Enabled: true
|
|
@@ -445,9 +456,10 @@ Rails/EnvironmentVariableAccess:
|
|
|
445
456
|
# TODO: Set to `pending` status in RuboCop Rails 2 series when migration doc will be written.
|
|
446
457
|
Enabled: false
|
|
447
458
|
VersionAdded: '2.10'
|
|
448
|
-
VersionChanged: '2.
|
|
459
|
+
VersionChanged: '2.24'
|
|
449
460
|
Include:
|
|
450
461
|
- app/**/*.rb
|
|
462
|
+
- config/initializers/**/*.rb
|
|
451
463
|
- lib/**/*.rb
|
|
452
464
|
Exclude:
|
|
453
465
|
- lib/**/*.rake
|
|
@@ -691,7 +703,7 @@ Rails/NegateInclude:
|
|
|
691
703
|
VersionChanged: '2.9'
|
|
692
704
|
|
|
693
705
|
Rails/NotNullColumn:
|
|
694
|
-
Description: 'Do not add a NOT NULL column without a default value.'
|
|
706
|
+
Description: 'Do not add a NOT NULL column without a default value to existing tables.'
|
|
695
707
|
Enabled: true
|
|
696
708
|
VersionAdded: '0.43'
|
|
697
709
|
VersionChanged: '2.20'
|
|
@@ -1016,8 +1028,9 @@ Rails/SkipsModelValidations:
|
|
|
1016
1028
|
See reference for more information.
|
|
1017
1029
|
Reference: 'https://guides.rubyonrails.org/active_record_validations.html#skipping-validations'
|
|
1018
1030
|
Enabled: true
|
|
1031
|
+
Safe: false
|
|
1019
1032
|
VersionAdded: '0.47'
|
|
1020
|
-
VersionChanged: '2.
|
|
1033
|
+
VersionChanged: '2.25'
|
|
1021
1034
|
ForbiddenMethods:
|
|
1022
1035
|
- decrement!
|
|
1023
1036
|
- decrement_counter
|
|
@@ -1161,8 +1174,9 @@ Rails/UnknownEnv:
|
|
|
1161
1174
|
|
|
1162
1175
|
Rails/UnusedIgnoredColumns:
|
|
1163
1176
|
Description: 'Remove a column that does not exist from `ignored_columns`.'
|
|
1164
|
-
Enabled:
|
|
1177
|
+
Enabled: false
|
|
1165
1178
|
VersionAdded: '2.11'
|
|
1179
|
+
VersionChanged: '2.25'
|
|
1166
1180
|
Include:
|
|
1167
1181
|
- app/models/**/*.rb
|
|
1168
1182
|
|
|
@@ -1181,12 +1195,12 @@ Rails/Validation:
|
|
|
1181
1195
|
- app/models/**/*.rb
|
|
1182
1196
|
|
|
1183
1197
|
Rails/WhereEquals:
|
|
1184
|
-
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.'
|
|
1185
1199
|
StyleGuide: 'https://rails.rubystyle.guide/#hash-conditions'
|
|
1186
1200
|
Enabled: 'pending'
|
|
1187
1201
|
SafeAutoCorrect: false
|
|
1188
1202
|
VersionAdded: '2.9'
|
|
1189
|
-
VersionChanged: '2.
|
|
1203
|
+
VersionChanged: '2.26'
|
|
1190
1204
|
|
|
1191
1205
|
Rails/WhereExists:
|
|
1192
1206
|
Description: 'Prefer `exists?(...)` over `where(...).exists?`.'
|
|
@@ -1219,10 +1233,21 @@ Rails/WhereNotWithMultipleConditions:
|
|
|
1219
1233
|
VersionAdded: '2.17'
|
|
1220
1234
|
VersionChanged: '2.18'
|
|
1221
1235
|
|
|
1236
|
+
Rails/WhereRange:
|
|
1237
|
+
Description: 'Use ranges in `where` instead of manually constructing SQL.'
|
|
1238
|
+
StyleGuide: 'https://rails.rubystyle.guide/#where-ranges'
|
|
1239
|
+
Enabled: pending
|
|
1240
|
+
SafeAutoCorrect: false
|
|
1241
|
+
VersionAdded: '2.25'
|
|
1242
|
+
|
|
1222
1243
|
# Accept `redirect_to(...) and return` and similar cases.
|
|
1223
1244
|
Style/AndOr:
|
|
1224
1245
|
EnforcedStyle: conditionals
|
|
1225
1246
|
|
|
1247
|
+
Style/CollectionCompact:
|
|
1248
|
+
AllowedReceivers:
|
|
1249
|
+
- params
|
|
1250
|
+
|
|
1226
1251
|
Style/FormatStringToken:
|
|
1227
1252
|
AllowedMethods:
|
|
1228
1253
|
- redirect
|
|
@@ -39,7 +39,12 @@ module RuboCop
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def schema
|
|
42
|
-
RuboCop
|
|
42
|
+
# For compatibility with RuboCop 1.61.0 or lower.
|
|
43
|
+
if respond_to?(:parser_engine)
|
|
44
|
+
RuboCop::Rails::SchemaLoader.load(target_ruby_version, parser_engine)
|
|
45
|
+
else
|
|
46
|
+
RuboCop::Rails::SchemaLoader.load(target_ruby_version, :parser_whitequark)
|
|
47
|
+
end
|
|
43
48
|
end
|
|
44
49
|
|
|
45
50
|
def table_name(class_node)
|
|
@@ -4,13 +4,40 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
# Common functionality for checking target rails version.
|
|
6
6
|
module TargetRailsVersion
|
|
7
|
+
# Informs the base RuboCop gem that it the Rails version is checked via `requires_gem` API,
|
|
8
|
+
# without needing to call this `#support_target_rails_version` method.
|
|
9
|
+
USES_REQUIRES_GEM_API = true
|
|
10
|
+
|
|
7
11
|
def minimum_target_rails_version(version)
|
|
8
|
-
|
|
12
|
+
if respond_to?(:requires_gem)
|
|
13
|
+
case version
|
|
14
|
+
when Integer, Float then requires_gem(TARGET_GEM_NAME, ">= #{version}")
|
|
15
|
+
when String then requires_gem(TARGET_GEM_NAME, version)
|
|
16
|
+
end
|
|
17
|
+
else
|
|
18
|
+
# Fallback path for previous versions of RuboCop which don't support the `requires_gem` API yet.
|
|
19
|
+
@minimum_target_rails_version = version
|
|
20
|
+
end
|
|
9
21
|
end
|
|
10
22
|
|
|
11
23
|
def support_target_rails_version?(version)
|
|
12
|
-
|
|
24
|
+
if respond_to?(:requires_gem)
|
|
25
|
+
return false unless gem_requirements
|
|
26
|
+
|
|
27
|
+
gem_requirement = gem_requirements[TARGET_GEM_NAME]
|
|
28
|
+
return true unless gem_requirement # If we have no requirement, then we support all versions
|
|
29
|
+
|
|
30
|
+
gem_requirement.satisfied_by?(Gem::Version.new(version))
|
|
31
|
+
else
|
|
32
|
+
# Fallback path for previous versions of RuboCop which don't support the `requires_gem` API yet.
|
|
33
|
+
@minimum_target_rails_version <= version
|
|
34
|
+
end
|
|
13
35
|
end
|
|
36
|
+
|
|
37
|
+
# Look for `railties` instead of `rails`, to support apps that only use a subset of `rails`
|
|
38
|
+
# See https://github.com/rubocop/rubocop/pull/11289
|
|
39
|
+
TARGET_GEM_NAME = 'railties'
|
|
40
|
+
private_constant :TARGET_GEM_NAME
|
|
14
41
|
end
|
|
15
42
|
end
|
|
16
43
|
end
|
|
@@ -99,6 +99,8 @@ module RuboCop
|
|
|
99
99
|
|
|
100
100
|
def use_redirect_to?(context)
|
|
101
101
|
context.right_siblings.compact.any? do |sibling|
|
|
102
|
+
# Unwrap `return redirect_to :index`
|
|
103
|
+
sibling = sibling.children.first if sibling.return_type? && sibling.children.one?
|
|
102
104
|
sibling.send_type? && sibling.method?(:redirect_to)
|
|
103
105
|
end
|
|
104
106
|
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)
|
|
@@ -55,15 +55,35 @@ module RuboCop
|
|
|
55
55
|
'ActiveSupport::TestCase' => 'active_support_test_case'
|
|
56
56
|
}.freeze
|
|
57
57
|
|
|
58
|
+
RAILS_5_2_LOAD_HOOKS = {
|
|
59
|
+
'ActiveRecord::ConnectionAdapters::SQLite3Adapter' => 'active_record_sqlite3adapter'
|
|
60
|
+
}.freeze
|
|
61
|
+
|
|
62
|
+
RAILS_7_1_LOAD_HOOKS = {
|
|
63
|
+
'ActiveRecord::TestFixtures' => 'active_record_fixtures',
|
|
64
|
+
'ActiveModel::Model' => 'active_model',
|
|
65
|
+
'ActionText::EncryptedRichText' => 'action_text_encrypted_rich_text',
|
|
66
|
+
'ActiveRecord::ConnectionAdapters::PostgreSQLAdapter' => 'active_record_postgresqladapter',
|
|
67
|
+
'ActiveRecord::ConnectionAdapters::Mysql2Adapter' => 'active_record_mysql2adapter',
|
|
68
|
+
'ActiveRecord::ConnectionAdapters::TrilogyAdapter' => 'active_record_trilogyadapter'
|
|
69
|
+
}.freeze
|
|
70
|
+
|
|
58
71
|
def on_send(node)
|
|
59
72
|
receiver, method, arguments = *node # rubocop:disable InternalAffairs/NodeDestructuring
|
|
60
|
-
return unless
|
|
73
|
+
return unless arguments && (hook = hook_for_const(receiver&.const_name))
|
|
61
74
|
|
|
62
75
|
preferred = "ActiveSupport.on_load(:#{hook}) { #{method} #{arguments.source} }"
|
|
63
76
|
add_offense(node, message: format(MSG, prefer: preferred, current: node.source)) do |corrector|
|
|
64
77
|
corrector.replace(node, preferred)
|
|
65
78
|
end
|
|
66
79
|
end
|
|
80
|
+
|
|
81
|
+
def hook_for_const(const_name)
|
|
82
|
+
hook = LOAD_HOOKS[const_name]
|
|
83
|
+
hook ||= RAILS_5_2_LOAD_HOOKS[const_name] if target_rails_version >= 5.2
|
|
84
|
+
hook ||= RAILS_7_1_LOAD_HOOKS[const_name] if target_rails_version >= 7.1
|
|
85
|
+
hook
|
|
86
|
+
end
|
|
67
87
|
end
|
|
68
88
|
end
|
|
69
89
|
end
|
|
@@ -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
|
|
@@ -113,8 +113,10 @@ module RuboCop
|
|
|
113
113
|
MYSQL_COMBINABLE_ALTER_METHODS = %i[rename_column add_index remove_index].freeze
|
|
114
114
|
|
|
115
115
|
POSTGRESQL_COMBINABLE_TRANSFORMATIONS = %i[change_default].freeze
|
|
116
|
+
POSTGRESQL_COMBINABLE_TRANSFORMATIONS_SINCE_6_1 = %i[change_null].freeze
|
|
116
117
|
|
|
117
118
|
POSTGRESQL_COMBINABLE_ALTER_METHODS = %i[change_column_default].freeze
|
|
119
|
+
POSTGRESQL_COMBINABLE_ALTER_METHODS_SINCE_6_1 = %i[change_column_null].freeze
|
|
118
120
|
|
|
119
121
|
def on_def(node)
|
|
120
122
|
return unless support_bulk_alter?
|
|
@@ -138,9 +140,9 @@ module RuboCop
|
|
|
138
140
|
return unless support_bulk_alter?
|
|
139
141
|
return unless node.command?(:change_table)
|
|
140
142
|
return if include_bulk_options?(node)
|
|
141
|
-
return unless node.block_node
|
|
143
|
+
return unless (body = node.block_node&.body)
|
|
142
144
|
|
|
143
|
-
send_nodes = send_nodes_from_change_table_block(
|
|
145
|
+
send_nodes = send_nodes_from_change_table_block(body)
|
|
144
146
|
|
|
145
147
|
add_offense_for_change_table(node) if count_transformations(send_nodes) > 1
|
|
146
148
|
end
|
|
@@ -196,7 +198,9 @@ module RuboCop
|
|
|
196
198
|
when MYSQL
|
|
197
199
|
COMBINABLE_ALTER_METHODS + MYSQL_COMBINABLE_ALTER_METHODS
|
|
198
200
|
when POSTGRESQL
|
|
199
|
-
COMBINABLE_ALTER_METHODS + POSTGRESQL_COMBINABLE_ALTER_METHODS
|
|
201
|
+
result = COMBINABLE_ALTER_METHODS + POSTGRESQL_COMBINABLE_ALTER_METHODS
|
|
202
|
+
result += POSTGRESQL_COMBINABLE_ALTER_METHODS_SINCE_6_1 if target_rails_version >= 6.1
|
|
203
|
+
result
|
|
200
204
|
end
|
|
201
205
|
end
|
|
202
206
|
|
|
@@ -205,7 +209,9 @@ module RuboCop
|
|
|
205
209
|
when MYSQL
|
|
206
210
|
COMBINABLE_TRANSFORMATIONS + MYSQL_COMBINABLE_TRANSFORMATIONS
|
|
207
211
|
when POSTGRESQL
|
|
208
|
-
COMBINABLE_TRANSFORMATIONS + POSTGRESQL_COMBINABLE_TRANSFORMATIONS
|
|
212
|
+
result = COMBINABLE_TRANSFORMATIONS + POSTGRESQL_COMBINABLE_TRANSFORMATIONS
|
|
213
|
+
result += POSTGRESQL_COMBINABLE_TRANSFORMATIONS_SINCE_6_1 if target_rails_version >= 6.1
|
|
214
|
+
result
|
|
209
215
|
end
|
|
210
216
|
end
|
|
211
217
|
|
|
@@ -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,10 @@ 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? }
|
|
28
|
+
# collection.filter(&:present?)
|
|
29
|
+
# collection.filter { |_k, v| v.present? }
|
|
27
30
|
#
|
|
28
31
|
# # good
|
|
29
32
|
# collection.compact_blank
|
|
@@ -31,8 +34,8 @@ module RuboCop
|
|
|
31
34
|
# # bad
|
|
32
35
|
# collection.delete_if(&:blank?) # Same behavior as `Array#compact_blank!` and `Hash#compact_blank!`
|
|
33
36
|
# collection.delete_if { |_k, v| v.blank? } # Same behavior as `Array#compact_blank!` and `Hash#compact_blank!`
|
|
34
|
-
# collection.
|
|
35
|
-
# collection.
|
|
37
|
+
# collection.keep_if(&:present?) # Same behavior as `Array#compact_blank!` and `Hash#compact_blank!`
|
|
38
|
+
# collection.keep_if { |_k, v| v.present? } # Same behavior as `Array#compact_blank!` and `Hash#compact_blank!`
|
|
36
39
|
#
|
|
37
40
|
# # good
|
|
38
41
|
# collection.compact_blank!
|
|
@@ -43,25 +46,41 @@ module RuboCop
|
|
|
43
46
|
extend TargetRailsVersion
|
|
44
47
|
|
|
45
48
|
MSG = 'Use `%<preferred_method>s` instead.'
|
|
46
|
-
RESTRICT_ON_SEND = %i[reject delete_if
|
|
49
|
+
RESTRICT_ON_SEND = %i[reject delete_if select filter keep_if].freeze
|
|
50
|
+
DESTRUCTIVE_METHODS = %i[delete_if keep_if].freeze
|
|
47
51
|
|
|
48
52
|
minimum_target_rails_version 6.1
|
|
49
53
|
|
|
50
54
|
def_node_matcher :reject_with_block?, <<~PATTERN
|
|
51
55
|
(block
|
|
52
|
-
(send _ {:reject :delete_if
|
|
56
|
+
(send _ {:reject :delete_if})
|
|
53
57
|
$(args ...)
|
|
54
58
|
(send
|
|
55
59
|
$(lvar _) :blank?))
|
|
56
60
|
PATTERN
|
|
57
61
|
|
|
58
62
|
def_node_matcher :reject_with_block_pass?, <<~PATTERN
|
|
59
|
-
(send _ {:reject :delete_if
|
|
63
|
+
(send _ {:reject :delete_if}
|
|
60
64
|
(block_pass
|
|
61
65
|
(sym :blank?)))
|
|
62
66
|
PATTERN
|
|
63
67
|
|
|
68
|
+
def_node_matcher :select_with_block?, <<~PATTERN
|
|
69
|
+
(block
|
|
70
|
+
(send _ {:select :filter :keep_if})
|
|
71
|
+
$(args ...)
|
|
72
|
+
(send
|
|
73
|
+
$(lvar _) :present?))
|
|
74
|
+
PATTERN
|
|
75
|
+
|
|
76
|
+
def_node_matcher :select_with_block_pass?, <<~PATTERN
|
|
77
|
+
(send _ {:select :filter :keep_if}
|
|
78
|
+
(block-pass
|
|
79
|
+
(sym :present?)))
|
|
80
|
+
PATTERN
|
|
81
|
+
|
|
64
82
|
def on_send(node)
|
|
83
|
+
return if target_ruby_version < 2.6 && node.method?(:filter)
|
|
65
84
|
return unless bad_method?(node)
|
|
66
85
|
|
|
67
86
|
range = offense_range(node)
|
|
@@ -75,8 +94,10 @@ module RuboCop
|
|
|
75
94
|
|
|
76
95
|
def bad_method?(node)
|
|
77
96
|
return true if reject_with_block_pass?(node)
|
|
97
|
+
return true if select_with_block_pass?(node)
|
|
78
98
|
|
|
79
|
-
|
|
99
|
+
arguments, receiver_in_block = reject_with_block?(node.parent) || select_with_block?(node.parent)
|
|
100
|
+
if arguments
|
|
80
101
|
return use_single_value_block_argument?(arguments, receiver_in_block) ||
|
|
81
102
|
use_hash_value_block_argument?(arguments, receiver_in_block)
|
|
82
103
|
end
|
|
@@ -103,7 +124,7 @@ module RuboCop
|
|
|
103
124
|
end
|
|
104
125
|
|
|
105
126
|
def preferred_method(node)
|
|
106
|
-
|
|
127
|
+
DESTRUCTIVE_METHODS.include?(node.method_name) ? 'compact_blank!' : 'compact_blank'
|
|
107
128
|
end
|
|
108
129
|
end
|
|
109
130
|
end
|
|
@@ -31,7 +31,7 @@ module RuboCop
|
|
|
31
31
|
time
|
|
32
32
|
].to_set.freeze
|
|
33
33
|
|
|
34
|
-
# Generated from `ActiveRecord::AttributeMethods.dangerous_attribute_methods` on activerecord 7.1.
|
|
34
|
+
# Generated from `ActiveRecord::AttributeMethods.dangerous_attribute_methods` on activerecord 7.1.3.
|
|
35
35
|
# rubocop:disable Metrics/CollectionLiteralLength
|
|
36
36
|
DANGEROUS_COLUMN_NAMES = %w[
|
|
37
37
|
__callbacks
|
|
@@ -290,7 +290,6 @@ module RuboCop
|
|
|
290
290
|
new_record
|
|
291
291
|
no_touching
|
|
292
292
|
normalize_reflection_attribute
|
|
293
|
-
object_id
|
|
294
293
|
partial_inserts
|
|
295
294
|
partial_updates
|
|
296
295
|
perform_validations
|
|
@@ -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
|