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.
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