rubocop-rails 2.20.2 → 2.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +9 -7
- data/config/default.yml +81 -12
- data/lib/rubocop/cop/mixin/active_record_helper.rb +15 -3
- data/lib/rubocop/cop/mixin/database_type_resolvable.rb +66 -0
- data/lib/rubocop/cop/mixin/index_method.rb +2 -2
- data/lib/rubocop/cop/mixin/target_rails_version.rb +29 -2
- data/lib/rubocop/cop/rails/action_controller_flash_before_render.rb +3 -1
- data/lib/rubocop/cop/rails/action_controller_test_case.rb +2 -2
- data/lib/rubocop/cop/rails/action_filter.rb +3 -0
- data/lib/rubocop/cop/rails/active_record_aliases.rb +2 -2
- data/lib/rubocop/cop/rails/active_support_aliases.rb +6 -5
- data/lib/rubocop/cop/rails/active_support_on_load.rb +21 -1
- data/lib/rubocop/cop/rails/after_commit_override.rb +1 -1
- data/lib/rubocop/cop/rails/bulk_change_table.rb +8 -41
- data/lib/rubocop/cop/rails/content_tag.rb +1 -1
- data/lib/rubocop/cop/rails/dangerous_column_names.rb +446 -0
- data/lib/rubocop/cop/rails/date.rb +1 -1
- data/lib/rubocop/cop/rails/duplicate_association.rb +69 -12
- data/lib/rubocop/cop/rails/dynamic_find_by.rb +3 -3
- data/lib/rubocop/cop/rails/eager_evaluation_log_message.rb +2 -2
- data/lib/rubocop/cop/rails/env_local.rb +46 -0
- data/lib/rubocop/cop/rails/expanded_date_range.rb +1 -1
- data/lib/rubocop/cop/rails/file_path.rb +9 -6
- data/lib/rubocop/cop/rails/find_by.rb +3 -3
- data/lib/rubocop/cop/rails/find_by_id.rb +9 -23
- data/lib/rubocop/cop/rails/freeze_time.rb +1 -1
- data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +1 -1
- data/lib/rubocop/cop/rails/helper_instance_variable.rb +1 -1
- data/lib/rubocop/cop/rails/http_status.rb +16 -5
- data/lib/rubocop/cop/rails/i18n_lazy_lookup.rb +63 -13
- data/lib/rubocop/cop/rails/inquiry.rb +1 -0
- data/lib/rubocop/cop/rails/inverse_of.rb +1 -1
- data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +7 -8
- data/lib/rubocop/cop/rails/not_null_column.rb +94 -6
- data/lib/rubocop/cop/rails/output.rb +3 -2
- data/lib/rubocop/cop/rails/pick.rb +10 -5
- data/lib/rubocop/cop/rails/pluck.rb +1 -1
- data/lib/rubocop/cop/rails/pluck_id.rb +2 -1
- data/lib/rubocop/cop/rails/pluck_in_where.rb +18 -5
- data/lib/rubocop/cop/rails/rake_environment.rb +22 -6
- data/lib/rubocop/cop/rails/redundant_active_record_all_method.rb +219 -0
- data/lib/rubocop/cop/rails/redundant_presence_validation_on_belongs_to.rb +7 -0
- data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +1 -1
- data/lib/rubocop/cop/rails/response_parsed_body.rb +52 -10
- data/lib/rubocop/cop/rails/reversible_migration.rb +4 -4
- data/lib/rubocop/cop/rails/root_pathname_methods.rb +38 -4
- data/lib/rubocop/cop/rails/save_bang.rb +15 -8
- data/lib/rubocop/cop/rails/schema_comment.rb +16 -10
- data/lib/rubocop/cop/rails/select_map.rb +78 -0
- data/lib/rubocop/cop/rails/skips_model_validations.rb +1 -1
- data/lib/rubocop/cop/rails/time_zone.rb +13 -5
- data/lib/rubocop/cop/rails/transaction_exit_statement.rb +29 -10
- data/lib/rubocop/cop/rails/uniq_before_pluck.rb +12 -4
- data/lib/rubocop/cop/rails/unique_validation_without_index.rb +2 -2
- data/lib/rubocop/cop/rails/unknown_env.rb +5 -1
- data/lib/rubocop/cop/rails/unused_ignored_columns.rb +6 -0
- data/lib/rubocop/cop/rails/unused_render_content.rb +67 -0
- data/lib/rubocop/cop/rails/validation.rb +6 -4
- data/lib/rubocop/cop/rails/where_equals.rb +3 -2
- data/lib/rubocop/cop/rails/where_exists.rb +9 -9
- data/lib/rubocop/cop/rails/where_missing.rb +6 -2
- data/lib/rubocop/cop/rails/where_not.rb +8 -6
- data/lib/rubocop/cop/rails/where_range.rb +157 -0
- data/lib/rubocop/cop/rails_cops.rb +7 -0
- data/lib/rubocop/rails/schema_loader/schema.rb +3 -2
- data/lib/rubocop/rails/schema_loader.rb +5 -15
- data/lib/rubocop/rails/version.rb +1 -1
- data/lib/rubocop-rails.rb +8 -0
- metadata +31 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cad5e6d0c6f188b6ff87adb04fbfb73c7c574b901de45256eb7fa6e50b7a136d
|
4
|
+
data.tar.gz: c8ab8f1d1c3284054af5847231dd996df24ee5441f638f95bc7e32420a3baf04
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea0ebe45e988d115aa45d7bdba2b728b0583e1e2d996d43af424eb8abc17ced35b528741fcc47b8b258de52edd2fb7bc1c92dd609b49ddeeaaaf26bce123e783
|
7
|
+
data.tar.gz: 7eb06cfce19f2a4ba78c6d571c65cf386e211b48ca2c9b5b9ca436ec9055e49f9737cbb3f9ce1b44ab432de87121295439effc59f093446cea88199bd08ba8a4
|
data/README.md
CHANGED
@@ -56,6 +56,8 @@ Note: `--rails` option is required while `rubocop` command supports `--rails` op
|
|
56
56
|
### Rake task
|
57
57
|
|
58
58
|
```ruby
|
59
|
+
require 'rubocop/rake_task'
|
60
|
+
|
59
61
|
RuboCop::RakeTask.new do |task|
|
60
62
|
task.requires << 'rubocop-rails'
|
61
63
|
end
|
@@ -64,21 +66,21 @@ end
|
|
64
66
|
## Rails configuration tip
|
65
67
|
|
66
68
|
If you are using Rails 6.1 or newer, add the following `config.generators.after_generate` setting to
|
67
|
-
your config/
|
69
|
+
your `config/environments/development.rb` to apply RuboCop autocorrection to code generated by `bin/rails g`.
|
68
70
|
|
69
71
|
```ruby
|
70
|
-
# config/
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
72
|
+
# config/environments/development.rb
|
73
|
+
Rails.application.configure do
|
74
|
+
config.generators.after_generate do |files|
|
75
|
+
parsable_files = files.filter { |file| file.end_with?('.rb') }
|
76
|
+
unless parsable_files.empty?
|
75
77
|
system("bundle exec rubocop -A --fail-level=E #{parsable_files.shelljoin}", exception: true)
|
76
78
|
end
|
77
79
|
end
|
78
80
|
end
|
79
81
|
```
|
80
82
|
|
81
|
-
It uses `rubocop -A` to apply `Style/FrozenStringLiteralComment` and other unsafe
|
83
|
+
It uses `rubocop -A` to apply `Style/FrozenStringLiteralComment` and other unsafe autocorrection cops.
|
82
84
|
`rubocop -A` is unsafe autocorrection, but code generated by default is simple and less likely to
|
83
85
|
be incompatible with `rubocop -A`. If you have problems you can replace it with `rubocop -a` instead.
|
84
86
|
|
data/config/default.yml
CHANGED
@@ -61,6 +61,18 @@ Lint/RedundantSafeNavigation:
|
|
61
61
|
- presence
|
62
62
|
- present?
|
63
63
|
|
64
|
+
Lint/SafeNavigationChain:
|
65
|
+
# Add `presence_in` method to the default of the RuboCop core:
|
66
|
+
# https://github.com/rubocop/rubocop/blob/v1.56.0/config/default.yml#L2265-L2271
|
67
|
+
AllowedMethods:
|
68
|
+
- present?
|
69
|
+
- blank?
|
70
|
+
- presence
|
71
|
+
- presence_in
|
72
|
+
- try
|
73
|
+
- try!
|
74
|
+
- in?
|
75
|
+
|
64
76
|
Rails:
|
65
77
|
Enabled: true
|
66
78
|
DocumentationBaseURL: https://docs.rubocop.org/rubocop-rails
|
@@ -83,8 +95,9 @@ Rails/ActionControllerTestCase:
|
|
83
95
|
|
84
96
|
Rails/ActionFilter:
|
85
97
|
Description: 'Enforces consistent use of action filter methods.'
|
86
|
-
Enabled:
|
98
|
+
Enabled: false
|
87
99
|
VersionAdded: '0.19'
|
100
|
+
VersionChanged: '2.22'
|
88
101
|
EnforcedStyle: action
|
89
102
|
SupportedStyles:
|
90
103
|
- action
|
@@ -152,6 +165,7 @@ Rails/ActiveSupportOnLoad:
|
|
152
165
|
- 'https://guides.rubyonrails.org/engines.html#available-load-hooks'
|
153
166
|
SafeAutoCorrect: false
|
154
167
|
VersionAdded: '2.16'
|
168
|
+
VersionChanged: '2.24'
|
155
169
|
|
156
170
|
Rails/AddColumnIndex:
|
157
171
|
Description: >-
|
@@ -296,6 +310,15 @@ Rails/CreateTableWithTimestamps:
|
|
296
310
|
- db/**/*_create_active_storage_tables.active_storage.rb
|
297
311
|
- db/**/*_create_active_storage_variant_records.active_storage.rb
|
298
312
|
|
313
|
+
Rails/DangerousColumnNames:
|
314
|
+
Description: >-
|
315
|
+
Avoid dangerous column names.
|
316
|
+
Enabled: pending
|
317
|
+
Severity: warning
|
318
|
+
VersionAdded: '2.21'
|
319
|
+
Include:
|
320
|
+
- 'db/**/*.rb'
|
321
|
+
|
299
322
|
Rails/Date:
|
300
323
|
Description: >-
|
301
324
|
Checks the correct usage of date aware methods,
|
@@ -317,7 +340,6 @@ Rails/Date:
|
|
317
340
|
|
318
341
|
Rails/DefaultScope:
|
319
342
|
Description: 'Avoid use of `default_scope`.'
|
320
|
-
StyleGuide: 'https://rails.rubystyle.guide#avoid-default-scope'
|
321
343
|
Enabled: false
|
322
344
|
VersionAdded: '2.7'
|
323
345
|
|
@@ -409,6 +431,11 @@ Rails/EnumUniqueness:
|
|
409
431
|
Include:
|
410
432
|
- app/models/**/*.rb
|
411
433
|
|
434
|
+
Rails/EnvLocal:
|
435
|
+
Description: 'Use `Rails.env.local?` instead of `Rails.env.development? || Rails.env.test?`.'
|
436
|
+
Enabled: pending
|
437
|
+
VersionAdded: '2.22'
|
438
|
+
|
412
439
|
Rails/EnvironmentComparison:
|
413
440
|
Description: "Favor `Rails.env.production?` over `Rails.env == 'production'`."
|
414
441
|
Enabled: true
|
@@ -419,9 +446,10 @@ Rails/EnvironmentVariableAccess:
|
|
419
446
|
# TODO: Set to `pending` status in RuboCop Rails 2 series when migration doc will be written.
|
420
447
|
Enabled: false
|
421
448
|
VersionAdded: '2.10'
|
422
|
-
VersionChanged: '2.
|
449
|
+
VersionChanged: '2.24'
|
423
450
|
Include:
|
424
451
|
- app/**/*.rb
|
452
|
+
- config/initializers/**/*.rb
|
425
453
|
- lib/**/*.rb
|
426
454
|
Exclude:
|
427
455
|
- lib/**/*.rake
|
@@ -463,10 +491,8 @@ Rails/FindBy:
|
|
463
491
|
StyleGuide: 'https://rails.rubystyle.guide#find_by'
|
464
492
|
Enabled: true
|
465
493
|
VersionAdded: '0.30'
|
466
|
-
VersionChanged: '2.
|
494
|
+
VersionChanged: '2.21'
|
467
495
|
IgnoreWhereFirst: true
|
468
|
-
Include:
|
469
|
-
- app/models/**/*.rb
|
470
496
|
|
471
497
|
Rails/FindById:
|
472
498
|
Description: >-
|
@@ -482,9 +508,7 @@ Rails/FindEach:
|
|
482
508
|
Enabled: true
|
483
509
|
Safe: false
|
484
510
|
VersionAdded: '0.30'
|
485
|
-
VersionChanged: '2.
|
486
|
-
Include:
|
487
|
-
- app/models/**/*.rb
|
511
|
+
VersionChanged: '2.21'
|
488
512
|
AllowedMethods:
|
489
513
|
# Methods that don't work well with `find_each`.
|
490
514
|
- order
|
@@ -547,6 +571,10 @@ Rails/I18nLazyLookup:
|
|
547
571
|
Reference: 'https://guides.rubyonrails.org/i18n.html#lazy-lookup'
|
548
572
|
Enabled: pending
|
549
573
|
VersionAdded: '2.14'
|
574
|
+
EnforcedStyle: lazy
|
575
|
+
SupportedStyles:
|
576
|
+
- lazy
|
577
|
+
- explicit
|
550
578
|
Include:
|
551
579
|
- 'app/controllers/**/*.rb'
|
552
580
|
|
@@ -665,10 +693,13 @@ Rails/NegateInclude:
|
|
665
693
|
VersionChanged: '2.9'
|
666
694
|
|
667
695
|
Rails/NotNullColumn:
|
668
|
-
Description: 'Do not add a NOT NULL column without a default value.'
|
696
|
+
Description: 'Do not add a NOT NULL column without a default value to existing tables.'
|
669
697
|
Enabled: true
|
670
698
|
VersionAdded: '0.43'
|
671
699
|
VersionChanged: '2.20'
|
700
|
+
Database: null
|
701
|
+
SupportedDatabases:
|
702
|
+
- mysql
|
672
703
|
Include:
|
673
704
|
- db/**/*.rb
|
674
705
|
|
@@ -775,6 +806,16 @@ Rails/ReadWriteAttribute:
|
|
775
806
|
Include:
|
776
807
|
- app/models/**/*.rb
|
777
808
|
|
809
|
+
Rails/RedundantActiveRecordAllMethod:
|
810
|
+
Description: Detect redundant `all` used as a receiver for Active Record query methods.
|
811
|
+
StyleGuide: 'https://rails.rubystyle.guide/#redundant-all'
|
812
|
+
Enabled: pending
|
813
|
+
Safe: false
|
814
|
+
AllowedReceivers:
|
815
|
+
- ActionMailer::Preview
|
816
|
+
- ActiveSupport::TimeZone
|
817
|
+
VersionAdded: '2.21'
|
818
|
+
|
778
819
|
Rails/RedundantAllowNil:
|
779
820
|
Description: >-
|
780
821
|
Finds redundant use of `allow_nil` when `allow_blank` is set to
|
@@ -863,7 +904,7 @@ Rails/RequireDependency:
|
|
863
904
|
VersionAdded: '2.10'
|
864
905
|
|
865
906
|
Rails/ResponseParsedBody:
|
866
|
-
Description: Prefer `response.parsed_body` to `
|
907
|
+
Description: Prefer `response.parsed_body` to custom parsing logic for `response.body`.
|
867
908
|
Enabled: pending
|
868
909
|
Safe: false
|
869
910
|
VersionAdded: '2.18'
|
@@ -955,6 +996,12 @@ Rails/ScopeArgs:
|
|
955
996
|
Include:
|
956
997
|
- app/models/**/*.rb
|
957
998
|
|
999
|
+
Rails/SelectMap:
|
1000
|
+
Description: 'Checks for uses of `select(:column_name)` with `map(&:column_name)`.'
|
1001
|
+
Enabled: pending
|
1002
|
+
Safe: false
|
1003
|
+
VersionAdded: '2.21'
|
1004
|
+
|
958
1005
|
Rails/ShortI18n:
|
959
1006
|
Description: 'Use the short form of the I18n methods: `t` instead of `translate` and `l` instead of `localize`.'
|
960
1007
|
StyleGuide: 'https://rails.rubystyle.guide/#short-i18n'
|
@@ -1083,6 +1130,7 @@ Rails/TransactionExitStatement:
|
|
1083
1130
|
- https://github.com/rails/rails/commit/15aa4200e083
|
1084
1131
|
Enabled: pending
|
1085
1132
|
VersionAdded: '2.14'
|
1133
|
+
TransactionMethods: []
|
1086
1134
|
|
1087
1135
|
Rails/UniqBeforePluck:
|
1088
1136
|
Description: 'Prefer the use of uniq or distinct before pluck.'
|
@@ -1115,11 +1163,18 @@ Rails/UnknownEnv:
|
|
1115
1163
|
|
1116
1164
|
Rails/UnusedIgnoredColumns:
|
1117
1165
|
Description: 'Remove a column that does not exist from `ignored_columns`.'
|
1118
|
-
Enabled:
|
1166
|
+
Enabled: false
|
1119
1167
|
VersionAdded: '2.11'
|
1168
|
+
VersionChanged: '2.25'
|
1120
1169
|
Include:
|
1121
1170
|
- app/models/**/*.rb
|
1122
1171
|
|
1172
|
+
Rails/UnusedRenderContent:
|
1173
|
+
Description: 'Do not specify body content for a response with a non-content status code.'
|
1174
|
+
Enabled: pending
|
1175
|
+
Severity: warning
|
1176
|
+
VersionAdded: '2.21'
|
1177
|
+
|
1123
1178
|
Rails/Validation:
|
1124
1179
|
Description: 'Use validates :attribute, hash of validations.'
|
1125
1180
|
Enabled: true
|
@@ -1167,6 +1222,12 @@ Rails/WhereNotWithMultipleConditions:
|
|
1167
1222
|
VersionAdded: '2.17'
|
1168
1223
|
VersionChanged: '2.18'
|
1169
1224
|
|
1225
|
+
Rails/WhereRange:
|
1226
|
+
Description: 'Use ranges in `where` instead of manually constructing SQL.'
|
1227
|
+
StyleGuide: 'https://rails.rubystyle.guide/#where-ranges'
|
1228
|
+
Enabled: pending
|
1229
|
+
VersionAdded: '2.25'
|
1230
|
+
|
1170
1231
|
# Accept `redirect_to(...) and return` and similar cases.
|
1171
1232
|
Style/AndOr:
|
1172
1233
|
EnforcedStyle: conditionals
|
@@ -1175,6 +1236,14 @@ Style/FormatStringToken:
|
|
1175
1236
|
AllowedMethods:
|
1176
1237
|
- redirect
|
1177
1238
|
|
1239
|
+
Style/InvertibleUnlessCondition:
|
1240
|
+
InverseMethods:
|
1241
|
+
# Active Support defines some common inverse methods. They are listed below:
|
1242
|
+
:present?: :blank?
|
1243
|
+
:blank?: :present?
|
1244
|
+
:include?: :exclude?
|
1245
|
+
:exclude?: :include?
|
1246
|
+
|
1178
1247
|
Style/SymbolProc:
|
1179
1248
|
AllowedMethods:
|
1180
1249
|
- define_method
|
@@ -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)
|
@@ -98,8 +103,15 @@ module RuboCop
|
|
98
103
|
end
|
99
104
|
|
100
105
|
def in_where?(node)
|
101
|
-
send_node = node.each_ancestor(:send).first
|
102
|
-
|
106
|
+
send_node = node.each_ancestor(:send, :csend).first
|
107
|
+
return false unless send_node
|
108
|
+
|
109
|
+
return true if WHERE_METHODS.include?(send_node.method_name)
|
110
|
+
|
111
|
+
receiver = send_node.receiver
|
112
|
+
return false unless receiver&.send_type?
|
113
|
+
|
114
|
+
send_node.method?(:not) && WHERE_METHODS.include?(receiver.method_name)
|
103
115
|
end
|
104
116
|
end
|
105
117
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# A mixin to extend cops in order to determine the database type.
|
6
|
+
#
|
7
|
+
# This module automatically detect an adapter from `development` environment
|
8
|
+
# in `config/database.yml` or the environment variable `DATABASE_URL`
|
9
|
+
# when the `Database` option is not set.
|
10
|
+
module DatabaseTypeResolvable
|
11
|
+
MYSQL = 'mysql'
|
12
|
+
POSTGRESQL = 'postgresql'
|
13
|
+
|
14
|
+
def database
|
15
|
+
cop_config['Database'] || database_from_yaml || database_from_env
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def database_from_yaml
|
21
|
+
return unless database_yaml
|
22
|
+
|
23
|
+
case database_adapter
|
24
|
+
when 'mysql2', 'trilogy'
|
25
|
+
MYSQL
|
26
|
+
when 'postgresql', 'postgis'
|
27
|
+
POSTGRESQL
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def database_from_env
|
32
|
+
url = ENV['DATABASE_URL'].presence
|
33
|
+
return unless url
|
34
|
+
|
35
|
+
case url
|
36
|
+
when %r{\A(mysql2|trilogy)://}
|
37
|
+
MYSQL
|
38
|
+
when %r{\Apostgres(ql)?://}
|
39
|
+
POSTGRESQL
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def database_yaml
|
44
|
+
return unless File.exist?('config/database.yml')
|
45
|
+
|
46
|
+
yaml = if YAML.respond_to?(:unsafe_load_file)
|
47
|
+
YAML.unsafe_load_file('config/database.yml')
|
48
|
+
else
|
49
|
+
YAML.load_file('config/database.yml')
|
50
|
+
end
|
51
|
+
return unless yaml.is_a? Hash
|
52
|
+
|
53
|
+
config = yaml['development']
|
54
|
+
return unless config.is_a?(Hash)
|
55
|
+
|
56
|
+
config
|
57
|
+
rescue Psych::SyntaxError
|
58
|
+
# noop
|
59
|
+
end
|
60
|
+
|
61
|
+
def database_adapter
|
62
|
+
database_yaml['adapter'] || database_yaml.first.last['adapter']
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -102,7 +102,7 @@ module RuboCop
|
|
102
102
|
end
|
103
103
|
|
104
104
|
# Internal helper class to hold match data
|
105
|
-
Captures = Struct.new(
|
105
|
+
Captures = ::Struct.new(
|
106
106
|
:transformed_argname,
|
107
107
|
:transforming_body_expr
|
108
108
|
) do
|
@@ -112,7 +112,7 @@ module RuboCop
|
|
112
112
|
end
|
113
113
|
|
114
114
|
# Internal helper class to hold autocorrect data
|
115
|
-
Autocorrection = Struct.new(:match, :block_node, :leading, :trailing) do
|
115
|
+
Autocorrection = ::Struct.new(:match, :block_node, :leading, :trailing) do
|
116
116
|
def self.from_each_with_object(node, match)
|
117
117
|
new(match, node, 0, 0)
|
118
118
|
end
|
@@ -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
|
@@ -85,7 +85,7 @@ module RuboCop
|
|
85
85
|
|
86
86
|
def inherit_action_controller_base?(node)
|
87
87
|
class_node = find_ancestor(node, type: :class)
|
88
|
-
return unless class_node
|
88
|
+
return false unless class_node
|
89
89
|
|
90
90
|
action_controller?(class_node)
|
91
91
|
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
|
@@ -3,8 +3,8 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Rails
|
6
|
-
# Using `ActionController::TestCase
|
7
|
-
# `ActionDispatch::IntegrationTest
|
6
|
+
# Using `ActionController::TestCase` is discouraged and should be replaced by
|
7
|
+
# `ActionDispatch::IntegrationTest`. Controller tests are too close to the
|
8
8
|
# internals of a controller whereas integration tests mimic the browser/user.
|
9
9
|
#
|
10
10
|
# @safety
|
@@ -8,6 +8,9 @@ module RuboCop
|
|
8
8
|
# The cop is configurable and can enforce the use of the older
|
9
9
|
# something_filter methods or the newer something_action methods.
|
10
10
|
#
|
11
|
+
# IMPORTANT: This cop is deprecated. Because the `*_filter` methods were removed in Rails 4.2,
|
12
|
+
# and that Rails version is no longer supported by RuboCop Rails. This cop will be removed in RuboCop Rails 3.0.
|
13
|
+
#
|
11
14
|
# @example EnforcedStyle: action (default)
|
12
15
|
# # bad
|
13
16
|
# after_filter :do_stuff
|
@@ -11,10 +11,10 @@ module RuboCop
|
|
11
11
|
# `update` but the method name remained same in the method definition.
|
12
12
|
#
|
13
13
|
# @example
|
14
|
-
# #bad
|
14
|
+
# # bad
|
15
15
|
# book.update_attributes!(author: 'Alice')
|
16
16
|
#
|
17
|
-
# #good
|
17
|
+
# # good
|
18
18
|
# book.update!(author: 'Alice')
|
19
19
|
class ActiveRecordAliases < Base
|
20
20
|
extend AutoCorrector
|
@@ -27,13 +27,13 @@ module RuboCop
|
|
27
27
|
|
28
28
|
ALIASES = {
|
29
29
|
starts_with?: {
|
30
|
-
original: :start_with?, matcher: '(
|
30
|
+
original: :start_with?, matcher: '(call str :starts_with? _)'
|
31
31
|
},
|
32
32
|
ends_with?: {
|
33
|
-
original: :end_with?, matcher: '(
|
33
|
+
original: :end_with?, matcher: '(call str :ends_with? _)'
|
34
34
|
},
|
35
|
-
append: { original: :<<, matcher: '(
|
36
|
-
prepend: { original: :unshift, matcher: '(
|
35
|
+
append: { original: :<<, matcher: '(call array :append _)' },
|
36
|
+
prepend: { original: :unshift, matcher: '(call array :prepend _)' }
|
37
37
|
}.freeze
|
38
38
|
|
39
39
|
ALIASES.each do |aliased_method, options|
|
@@ -47,13 +47,14 @@ module RuboCop
|
|
47
47
|
preferred_method = ALIASES[aliased_method][:original]
|
48
48
|
message = format(MSG, prefer: preferred_method, current: aliased_method)
|
49
49
|
|
50
|
-
add_offense(node, message: message) do |corrector|
|
50
|
+
add_offense(node.loc.selector.join(node.source_range.end), message: message) do |corrector|
|
51
51
|
next if append(node)
|
52
52
|
|
53
53
|
corrector.replace(node.loc.selector, preferred_method)
|
54
54
|
end
|
55
55
|
end
|
56
56
|
end
|
57
|
+
alias on_csend on_send
|
57
58
|
end
|
58
59
|
end
|
59
60
|
end
|
@@ -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
|
@@ -48,7 +48,7 @@ module RuboCop
|
|
48
48
|
seen_callback_names = {}
|
49
49
|
|
50
50
|
each_after_commit_callback(class_node) do |node|
|
51
|
-
callback_name = node.
|
51
|
+
callback_name = node.first_argument.value
|
52
52
|
if seen_callback_names.key?(callback_name)
|
53
53
|
add_offense(node, message: format(MSG, name: callback_name))
|
54
54
|
else
|
@@ -12,8 +12,9 @@ module RuboCop
|
|
12
12
|
# The `bulk` option is only supported on the MySQL and
|
13
13
|
# the PostgreSQL (5.2 later) adapter; thus it will
|
14
14
|
# automatically detect an adapter from `development` environment
|
15
|
-
# in `config/database.yml`
|
16
|
-
#
|
15
|
+
# in `config/database.yml` or the environment variable `DATABASE_URL`
|
16
|
+
# when the `Database` option is not set.
|
17
|
+
# If the adapter is not `mysql2`, `trilogy`, `postgresql`, or `postgis`,
|
17
18
|
# this Cop ignores offenses.
|
18
19
|
#
|
19
20
|
# @example
|
@@ -63,6 +64,8 @@ module RuboCop
|
|
63
64
|
# end
|
64
65
|
# end
|
65
66
|
class BulkChangeTable < Base
|
67
|
+
include DatabaseTypeResolvable
|
68
|
+
|
66
69
|
MSG_FOR_CHANGE_TABLE = <<~MSG.chomp
|
67
70
|
You can combine alter queries using `bulk: true` options.
|
68
71
|
MSG
|
@@ -70,9 +73,6 @@ module RuboCop
|
|
70
73
|
You can use `change_table :%<table>s, bulk: true` to combine alter queries.
|
71
74
|
MSG
|
72
75
|
|
73
|
-
MYSQL = 'mysql'
|
74
|
-
POSTGRESQL = 'postgresql'
|
75
|
-
|
76
76
|
MIGRATION_METHODS = %i[change up down].freeze
|
77
77
|
|
78
78
|
COMBINABLE_TRANSFORMATIONS = %i[
|
@@ -174,39 +174,6 @@ module RuboCop
|
|
174
174
|
options.hash_type? && options.keys.any? { |key| key.sym_type? && key.value == :bulk }
|
175
175
|
end
|
176
176
|
|
177
|
-
def database
|
178
|
-
cop_config['Database'] || database_from_yaml
|
179
|
-
end
|
180
|
-
|
181
|
-
def database_from_yaml
|
182
|
-
return nil unless database_yaml
|
183
|
-
|
184
|
-
case database_yaml['adapter']
|
185
|
-
when 'mysql2'
|
186
|
-
MYSQL
|
187
|
-
when 'postgresql'
|
188
|
-
POSTGRESQL
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
def database_yaml
|
193
|
-
return nil unless File.exist?('config/database.yml')
|
194
|
-
|
195
|
-
yaml = if YAML.respond_to?(:unsafe_load_file)
|
196
|
-
YAML.unsafe_load_file('config/database.yml')
|
197
|
-
else
|
198
|
-
YAML.load_file('config/database.yml')
|
199
|
-
end
|
200
|
-
return nil unless yaml.is_a? Hash
|
201
|
-
|
202
|
-
config = yaml['development']
|
203
|
-
return nil unless config.is_a?(Hash)
|
204
|
-
|
205
|
-
config
|
206
|
-
rescue Psych::SyntaxError
|
207
|
-
nil
|
208
|
-
end
|
209
|
-
|
210
177
|
def support_bulk_alter?
|
211
178
|
case database
|
212
179
|
when MYSQL
|
@@ -245,7 +212,7 @@ module RuboCop
|
|
245
212
|
# @param node [RuboCop::AST::SendNode]
|
246
213
|
def add_offense_for_alter_methods(node)
|
247
214
|
# arguments: [{(sym :table)(str "table")} ...]
|
248
|
-
table_node = node.
|
215
|
+
table_node = node.first_argument
|
249
216
|
return unless table_node.is_a? RuboCop::AST::BasicLiteralNode
|
250
217
|
|
251
218
|
message = format(MSG_FOR_ALTER_METHODS, table: table_node.value)
|
@@ -267,10 +234,10 @@ module RuboCop
|
|
267
234
|
# @param new_node [RuboCop::AST::SendNode]
|
268
235
|
def process(new_node)
|
269
236
|
# arguments: [{(sym :table)(str "table")} ...]
|
270
|
-
table_node = new_node.
|
237
|
+
table_node = new_node.first_argument
|
271
238
|
if table_node.is_a? RuboCop::AST::BasicLiteralNode
|
272
239
|
flush unless @nodes.all? do |node|
|
273
|
-
node.
|
240
|
+
node.first_argument.value.to_s == table_node.value.to_s
|
274
241
|
end
|
275
242
|
@nodes << new_node
|
276
243
|
else
|
@@ -7,7 +7,7 @@ module RuboCop
|
|
7
7
|
#
|
8
8
|
# NOTE: Allow `tag` when the first argument is a variable because
|
9
9
|
# `tag(name)` is simpler rather than `tag.public_send(name)`.
|
10
|
-
# And this cop will be renamed to something like `LegacyTag` in the future. (e.g. RuboCop Rails
|
10
|
+
# And this cop will be renamed to something like `LegacyTag` in the future. (e.g. RuboCop Rails 3.0)
|
11
11
|
#
|
12
12
|
# @example
|
13
13
|
# # bad
|