rubocop-rails 2.27.0 → 2.28.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8a20ef13a67612f99cb522625350e57836511b07a2666b75a8cbc556620adf01
4
- data.tar.gz: 436aaa2f094779e0101e17d2cb56f4a7bdd64fbf14360e9e22102be13da413af
3
+ metadata.gz: 758b691d39a36d50333d038d5efc0615f3da32aa8b47f0a465f684586b15463c
4
+ data.tar.gz: 8cf337b9a94306e55af10e5c7f0ee1e607fe22b27ca02cde32ece30e0c8c9bb5
5
5
  SHA512:
6
- metadata.gz: 4d73f8ec4a0567acff57d0e39b267a24ee615e58d20114fa8fd37d5614ea2d4b3e6435c9ed34db322d7368086f9df150de0646c5e63cfd2987d0847dc3abd057
7
- data.tar.gz: 93f42a0c60daec890a8cd363f588e37e5f65210d63dbb7e85e1c19cd32dc6459d6e593fbc3947b1cef832b981ca7b06bb5871c60cf6439a07e32c3df54257bcc
6
+ metadata.gz: b5841dbc4ae81e23e5eac1921e5752204e0c0dea5d17e0edd894329bd8d8764d0594b44a045f0d4f722d8b6927037f1b8817a1d29f444c75555ecd94feb8180d
7
+ data.tar.gz: 2adfb7937e87109d54e8fe596bc653528a62cfe87cebe7554ee1865a07daf5c3169fb7387bf6dacc59e71ee479ddd718c2775f2a1df573f5383b1f10fc27fd42
data/README.md CHANGED
@@ -83,6 +83,22 @@ gems.locked file to find the version of Rails that has been bound to the
83
83
  application. If neither of those files exist, RuboCop will use Rails 5.0
84
84
  as the default.
85
85
 
86
+ ### `AllCops: MigratedSchemaVersion`
87
+
88
+ By specifying the `MigratedSchemaVersion` option, migration files that have already been run can be ignored.
89
+ When `MigratedSchemaVersion: '20241225000000'` is set, migration files lower than or equal to '20241225000000' will be ignored.
90
+ For example, to ignore db/migrate/20241225000000_create_articles.rb and earlier migrations you would configure it the following way:
91
+
92
+ ```yaml
93
+ AllCops
94
+ MigratedSchemaVersion: '20241225000000'
95
+ ```
96
+
97
+ This prevents inspecting schema settings for already applied migration files.
98
+ Changing already applied migrations should be avoided because it can lead to the schema getting out of sync
99
+ between your local copy and what it actually is in production, depending on when `bin/rails db:migrate` was executed.
100
+ If you want to modify your schema to comply with the cops, you should instead create new migrations.
101
+
86
102
  ## Rails configuration tip
87
103
 
88
104
  In Rails 6.1+, add the following `config.generators.after_generate` setting to
data/config/default.yml CHANGED
@@ -25,6 +25,10 @@ AllCops:
25
25
  # application. If neither of those files exist, RuboCop will use Rails 5.0
26
26
  # as the default.
27
27
  TargetRailsVersion: ~
28
+ # By specifying `MigratedSchemaVersion` option, migration files that have been migrated can be ignored.
29
+ # When `MigratedSchemaVersion: '20241231000000'` is set. Migration files lower than or equal to '20250101000000' will be ignored.
30
+ # For example, this is the timestamp in db/migrate/20250101000000_create_articles.rb.
31
+ MigratedSchemaVersion: ~
28
32
 
29
33
  Lint/NumberConversion:
30
34
  # Add Rails' duration methods to the ignore list for `Lint/NumberConversion`
@@ -21,6 +21,35 @@ module RuboCop
21
21
  migration_class?(class_node)
22
22
  end
23
23
  end
24
+
25
+ # rubocop:disable Style/DocumentDynamicEvalDefinition
26
+ %i[on_send on_csend on_block on_numblock on_class].each do |method|
27
+ class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
28
+ def #{method}(node)
29
+ return if already_migrated_file?
30
+
31
+ super if method(__method__).super_method
32
+ end
33
+ RUBY
34
+ end
35
+ # rubocop:enable Style/DocumentDynamicEvalDefinition
36
+
37
+ private
38
+
39
+ def already_migrated_file?
40
+ return false unless migrated_schema_version
41
+
42
+ match_data = File.basename(processed_source.file_path).match(/(?<timestamp>\d{14})/)
43
+ schema_version = match_data['timestamp'] if match_data
44
+
45
+ return false unless schema_version
46
+
47
+ schema_version <= migrated_schema_version.to_s # Ignore applied migration files.
48
+ end
49
+
50
+ def migrated_schema_version
51
+ config.for_all_cops.fetch('MigratedSchemaVersion', nil)
52
+ end
24
53
  end
25
54
  end
26
55
  end
@@ -19,6 +19,7 @@ module RuboCop
19
19
  class AddColumnIndex < Base
20
20
  extend AutoCorrector
21
21
  include RangeHelp
22
+ prepend MigrationsHelper
22
23
 
23
24
  MSG = '`add_column` does not accept an `index` key, use `add_index` instead.'
24
25
  RESTRICT_ON_SEND = %i[add_column].freeze
@@ -65,6 +65,7 @@ module RuboCop
65
65
  # end
66
66
  class BulkChangeTable < Base
67
67
  include DatabaseTypeResolvable
68
+ prepend MigrationsHelper
68
69
 
69
70
  MSG_FOR_CHANGE_TABLE = <<~MSG.chomp
70
71
  You can combine alter queries using `bulk: true` options.
@@ -14,6 +14,8 @@ module RuboCop
14
14
  # # good
15
15
  # add_column :users, :saved
16
16
  class DangerousColumnNames < Base # rubocop:disable Metrics/ClassLength
17
+ prepend MigrationsHelper
18
+
17
19
  COLUMN_TYPE_METHOD_NAMES = %i[
18
20
  bigint
19
21
  binary
@@ -66,6 +66,8 @@ module RuboCop
66
66
 
67
67
  def on_send(node)
68
68
  check_for_file_join_with_rails_root(node)
69
+ return unless node.receiver
70
+
69
71
  check_for_rails_root_join_with_slash_separated_path(node)
70
72
  check_for_rails_root_join_with_string_arguments(node)
71
73
  end
@@ -76,6 +78,7 @@ module RuboCop
76
78
  rails_root_index = find_rails_root_index(node)
77
79
  slash_node = node.children[rails_root_index + 1]
78
80
  return unless slash_node&.str_type? && slash_node.source.start_with?(File::SEPARATOR)
81
+ return unless node.children[rails_root_index].children.first.send_type?
79
82
 
80
83
  register_offense(node, require_to_s: false) do |corrector|
81
84
  autocorrect_slash_after_rails_root_in_dstr(corrector, node, rails_root_index)
@@ -20,7 +20,7 @@ module RuboCop
20
20
  #
21
21
  class MigrationClassName < Base
22
22
  extend AutoCorrector
23
- include MigrationsHelper
23
+ prepend MigrationsHelper
24
24
 
25
25
  MSG = 'Replace with `%<camelized_basename>s` that matches the file name.'
26
26
 
@@ -41,6 +41,7 @@ module RuboCop
41
41
  # change_column_null :products, :category_id, false
42
42
  class NotNullColumn < Base
43
43
  include DatabaseTypeResolvable
44
+ prepend MigrationsHelper
44
45
 
45
46
  MSG = 'Do not add a NOT NULL column without a default value.'
46
47
  RESTRICT_ON_SEND = %i[add_column add_reference].freeze
@@ -9,6 +9,24 @@ module RuboCop
9
9
  # element in an enumerable. When called on an Active Record relation, it
10
10
  # results in a more efficient query that only selects the necessary key.
11
11
  #
12
+ # NOTE: If the receiver's relation is not loaded and `pluck` is used inside an iteration,
13
+ # it may result in N+1 queries because `pluck` queries the database on each iteration.
14
+ # This cop ignores offenses for `map/collect` when they are suspected to be part of an iteration
15
+ # to prevent such potential issues.
16
+ #
17
+ # [source,ruby]
18
+ # ----
19
+ # users = User.all
20
+ # 5.times do
21
+ # users.map { |user| user[:foo] } # Only one query is executed
22
+ # end
23
+ #
24
+ # users = User.all
25
+ # 5.times do
26
+ # users.pluck(:id) # A query is executed on every iteration
27
+ # end
28
+ # ----
29
+ #
12
30
  # @safety
13
31
  # This cop is unsafe because model can use column aliases.
14
32
  #
@@ -42,6 +60,8 @@ module RuboCop
42
60
  PATTERN
43
61
 
44
62
  def on_block(node)
63
+ return if node.each_ancestor(:block, :numblock).any?
64
+
45
65
  pluck_candidate?(node) do |argument, key|
46
66
  next if key.regexp_type? || !use_one_block_argument?(argument)
47
67
 
@@ -174,7 +174,7 @@ module RuboCop
174
174
  parent = node.parent
175
175
  return false unless POSSIBLE_ENUMERABLE_BLOCK_METHODS.include?(parent.method_name)
176
176
 
177
- parent.parent&.block_type? || parent.parent&.numblock_type? || parent.first_argument&.block_pass_type?
177
+ parent.block_literal? || parent.first_argument&.block_pass_type?
178
178
  end
179
179
 
180
180
  def sensitive_association_method?(node)
@@ -151,7 +151,7 @@ module RuboCop
151
151
  # remove_index :users, column: :email
152
152
  # end
153
153
  class ReversibleMigration < Base
154
- include MigrationsHelper
154
+ prepend MigrationsHelper
155
155
 
156
156
  MSG = '%<action>s is not reversible.'
157
157
 
@@ -43,7 +43,7 @@ module RuboCop
43
43
  # end
44
44
  # end
45
45
  class ReversibleMigrationMethodDefinition < Base
46
- include MigrationsHelper
46
+ prepend MigrationsHelper
47
47
 
48
48
  MSG = 'Migrations must contain either a `change` method, or both an `up` and a `down` method.'
49
49
 
@@ -244,7 +244,7 @@ module RuboCop
244
244
  end
245
245
 
246
246
  def operator_or_single_negative?(node)
247
- node.or_type? || node.and_type? || single_negative?(node)
247
+ node.operator_keyword? || single_negative?(node)
248
248
  end
249
249
 
250
250
  def conditional?(parent)
@@ -23,6 +23,7 @@ module RuboCop
23
23
  #
24
24
  class SchemaComment < Base
25
25
  include ActiveRecordMigrationsHelper
26
+ prepend MigrationsHelper
26
27
 
27
28
  COLUMN_MSG = 'New database column without `comment`.'
28
29
  TABLE_MSG = 'New database table without `comment`.'
@@ -54,7 +54,7 @@ module RuboCop
54
54
 
55
55
  # rubocop:disable Metrics/AbcSize
56
56
  def autocorrect(corrector, select_node, node, preferred_method)
57
- corrector.remove(select_node.loc.dot || node.loc.dot)
57
+ corrector.remove(select_node.parent.loc.dot)
58
58
  corrector.remove(select_node.loc.selector.begin.join(select_node.source_range.end))
59
59
  corrector.replace(node.loc.selector.begin.join(node.source_range.end), preferred_method)
60
60
  end
@@ -18,8 +18,9 @@ module RuboCop
18
18
  # t.boolean :active, default: true, null: false
19
19
  #
20
20
  class ThreeStateBooleanColumn < Base
21
- MSG = 'Boolean columns should always have a default value and a `NOT NULL` constraint.'
21
+ prepend MigrationsHelper
22
22
 
23
+ MSG = 'Boolean columns should always have a default value and a `NOT NULL` constraint.'
23
24
  RESTRICT_ON_SEND = %i[add_column column boolean].freeze
24
25
 
25
26
  def_node_matcher :three_state_boolean?, <<~PATTERN
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module Rails
5
5
  # This module holds the RuboCop Rails version information.
6
6
  module Version
7
- STRING = '2.27.0'
7
+ STRING = '2.28.0'
8
8
 
9
9
  def self.document_version
10
10
  STRING.match('\d+\.\d+').to_s
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.27.0
4
+ version: 2.28.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -9,7 +9,7 @@ authors:
9
9
  - Yuji Nakayama
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-10-26 00:00:00.000000000 Z
12
+ date: 2024-12-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -246,7 +246,7 @@ metadata:
246
246
  homepage_uri: https://docs.rubocop.org/rubocop-rails/
247
247
  changelog_uri: https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md
248
248
  source_code_uri: https://github.com/rubocop/rubocop-rails/
249
- documentation_uri: https://docs.rubocop.org/rubocop-rails/2.27/
249
+ documentation_uri: https://docs.rubocop.org/rubocop-rails/2.28/
250
250
  bug_tracker_uri: https://github.com/rubocop/rubocop-rails/issues
251
251
  rubygems_mfa_required: 'true'
252
252
  rdoc_options: []
@@ -263,7 +263,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
263
263
  - !ruby/object:Gem::Version
264
264
  version: '0'
265
265
  requirements: []
266
- rubygems_version: 3.6.0.dev
266
+ rubygems_version: 3.6.1
267
267
  specification_version: 4
268
268
  summary: Automatic Rails code style checking tool.
269
269
  test_files: []