rubocop-rails 2.20.2 → 2.25.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -7
  3. data/config/default.yml +81 -12
  4. data/lib/rubocop/cop/mixin/active_record_helper.rb +15 -3
  5. data/lib/rubocop/cop/mixin/database_type_resolvable.rb +66 -0
  6. data/lib/rubocop/cop/mixin/index_method.rb +2 -2
  7. data/lib/rubocop/cop/mixin/target_rails_version.rb +29 -2
  8. data/lib/rubocop/cop/rails/action_controller_flash_before_render.rb +3 -1
  9. data/lib/rubocop/cop/rails/action_controller_test_case.rb +2 -2
  10. data/lib/rubocop/cop/rails/action_filter.rb +3 -0
  11. data/lib/rubocop/cop/rails/active_record_aliases.rb +2 -2
  12. data/lib/rubocop/cop/rails/active_support_aliases.rb +6 -5
  13. data/lib/rubocop/cop/rails/active_support_on_load.rb +21 -1
  14. data/lib/rubocop/cop/rails/after_commit_override.rb +1 -1
  15. data/lib/rubocop/cop/rails/bulk_change_table.rb +8 -41
  16. data/lib/rubocop/cop/rails/content_tag.rb +1 -1
  17. data/lib/rubocop/cop/rails/dangerous_column_names.rb +446 -0
  18. data/lib/rubocop/cop/rails/date.rb +1 -1
  19. data/lib/rubocop/cop/rails/duplicate_association.rb +69 -12
  20. data/lib/rubocop/cop/rails/dynamic_find_by.rb +3 -3
  21. data/lib/rubocop/cop/rails/eager_evaluation_log_message.rb +2 -2
  22. data/lib/rubocop/cop/rails/env_local.rb +46 -0
  23. data/lib/rubocop/cop/rails/expanded_date_range.rb +1 -1
  24. data/lib/rubocop/cop/rails/file_path.rb +9 -6
  25. data/lib/rubocop/cop/rails/find_by.rb +3 -3
  26. data/lib/rubocop/cop/rails/find_by_id.rb +9 -23
  27. data/lib/rubocop/cop/rails/freeze_time.rb +1 -1
  28. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +1 -1
  29. data/lib/rubocop/cop/rails/helper_instance_variable.rb +1 -1
  30. data/lib/rubocop/cop/rails/http_status.rb +16 -5
  31. data/lib/rubocop/cop/rails/i18n_lazy_lookup.rb +63 -13
  32. data/lib/rubocop/cop/rails/inquiry.rb +1 -0
  33. data/lib/rubocop/cop/rails/inverse_of.rb +1 -1
  34. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +7 -8
  35. data/lib/rubocop/cop/rails/not_null_column.rb +94 -6
  36. data/lib/rubocop/cop/rails/output.rb +3 -2
  37. data/lib/rubocop/cop/rails/pick.rb +10 -5
  38. data/lib/rubocop/cop/rails/pluck.rb +1 -1
  39. data/lib/rubocop/cop/rails/pluck_id.rb +2 -1
  40. data/lib/rubocop/cop/rails/pluck_in_where.rb +18 -5
  41. data/lib/rubocop/cop/rails/rake_environment.rb +22 -6
  42. data/lib/rubocop/cop/rails/redundant_active_record_all_method.rb +219 -0
  43. data/lib/rubocop/cop/rails/redundant_presence_validation_on_belongs_to.rb +7 -0
  44. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +1 -1
  45. data/lib/rubocop/cop/rails/response_parsed_body.rb +52 -10
  46. data/lib/rubocop/cop/rails/reversible_migration.rb +4 -4
  47. data/lib/rubocop/cop/rails/root_pathname_methods.rb +38 -4
  48. data/lib/rubocop/cop/rails/save_bang.rb +15 -8
  49. data/lib/rubocop/cop/rails/schema_comment.rb +16 -10
  50. data/lib/rubocop/cop/rails/select_map.rb +78 -0
  51. data/lib/rubocop/cop/rails/skips_model_validations.rb +1 -1
  52. data/lib/rubocop/cop/rails/time_zone.rb +13 -5
  53. data/lib/rubocop/cop/rails/transaction_exit_statement.rb +29 -10
  54. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +12 -4
  55. data/lib/rubocop/cop/rails/unique_validation_without_index.rb +2 -2
  56. data/lib/rubocop/cop/rails/unknown_env.rb +5 -1
  57. data/lib/rubocop/cop/rails/unused_ignored_columns.rb +6 -0
  58. data/lib/rubocop/cop/rails/unused_render_content.rb +67 -0
  59. data/lib/rubocop/cop/rails/validation.rb +6 -4
  60. data/lib/rubocop/cop/rails/where_equals.rb +3 -2
  61. data/lib/rubocop/cop/rails/where_exists.rb +9 -9
  62. data/lib/rubocop/cop/rails/where_missing.rb +6 -2
  63. data/lib/rubocop/cop/rails/where_not.rb +8 -6
  64. data/lib/rubocop/cop/rails/where_range.rb +157 -0
  65. data/lib/rubocop/cop/rails_cops.rb +7 -0
  66. data/lib/rubocop/rails/schema_loader/schema.rb +3 -2
  67. data/lib/rubocop/rails/schema_loader.rb +5 -15
  68. data/lib/rubocop/rails/version.rb +1 -1
  69. data/lib/rubocop-rails.rb +8 -0
  70. metadata +31 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 227ce5b698e456412c24917c5644b2a938531440ab8c64e2b5036d6f2857a548
4
- data.tar.gz: 41c6157da73215cca0b5d56ffa254711c2f9f4f5399c8aa3d85ac7c719958b28
3
+ metadata.gz: cad5e6d0c6f188b6ff87adb04fbfb73c7c574b901de45256eb7fa6e50b7a136d
4
+ data.tar.gz: c8ab8f1d1c3284054af5847231dd996df24ee5441f638f95bc7e32420a3baf04
5
5
  SHA512:
6
- metadata.gz: afafd2f9293f4592cc914fdb42c6742900681574d5d0a27dc2031eddb3446b419ac04a77a149e0169ab89a0bb7afe4e0481b3ff889631345a0227b0d24a2c185
7
- data.tar.gz: a90108eed94c1cedbe1b9a059b60cae51465cffd5a8612f56a0548182b6f992e3e626125e4a4f2f74ceda491a91cdcacb0bd8206ebf94d7d245841572639b556
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/application.rb to apply RuboCop autocorrection to code generated by `bin/rails g`.
69
+ your `config/environments/development.rb` to apply RuboCop autocorrection to code generated by `bin/rails g`.
68
70
 
69
71
  ```ruby
70
- # config/application.rb
71
- module YourCoolApp
72
- class Application < Rails::Application
73
- config.generators.after_generate do |files|
74
- parsable_files = files.filter { |file| file.end_with?('.rb') }
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 autocorretion cops.
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: true
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.11'
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.11'
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.19'
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 `JSON.parse(response.body)`.
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: pending
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::Rails::SchemaLoader.load(target_ruby_version)
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
- send_node && WHERE_METHODS.include?(send_node.method_name)
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
- @minimum_target_rails_version = version
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
- @minimum_target_rails_version <= version
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`` is discouraged and should be replaced by
7
- # `ActionDispatch::IntegrationTest``. Controller tests are too close to the
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: '(send str :starts_with? _)'
30
+ original: :start_with?, matcher: '(call str :starts_with? _)'
31
31
  },
32
32
  ends_with?: {
33
- original: :end_with?, matcher: '(send str :ends_with? _)'
33
+ original: :end_with?, matcher: '(call str :ends_with? _)'
34
34
  },
35
- append: { original: :<<, matcher: '(send array :append _)' },
36
- prepend: { original: :unshift, matcher: '(send array :prepend _)' }
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 receiver && (hook = LOAD_HOOKS[receiver.const_name])
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.arguments[0].value
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` when the `Database` option is not set.
16
- # If the adapter is not `mysql2` or `postgresql`,
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.arguments[0]
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.arguments[0]
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.arguments[0].value.to_s == table_node.value.to_s
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 2.0)
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