rubocop-rails 2.13.1 → 2.13.2

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: 624c6bfb8dc9c5db0f6dd6bec835bd71e5e5a7aadc298342c15faae187226079
4
- data.tar.gz: 4354d39a8367f0e4cb46b5a890cdd0836bfff6d838b5ae320b3df3a480f529af
3
+ metadata.gz: 87ab88a596e8f8dbe2ef0ded9a93ae1ceba10572ad41fc6b4e1b0b684cf68110
4
+ data.tar.gz: 4bc8502424aa32efec36f06ca475b7a3918b160060f76aa65eba39bfa5a31947
5
5
  SHA512:
6
- metadata.gz: 19863e8b5b71b4403d66b46e73ed41ceb1953d2a68996fbcc800ab4c06fcf4dfebadf3907f62d2c575b002223a95fa67fce2412c01fa42b6234848c2791b37e9
7
- data.tar.gz: 1e3d14e3240f7fdb9182529865ee8257cf19368bac19c33abfba44b0a3b63c54e64457f73725e6c629a5846ea402a96e650f7d6ce0e1943386c857d6a8642d7b
6
+ metadata.gz: 27016cd823ac6eb75ddb06f97c613fea178b29dc8cadac6289c803a9745ccbe2ffd7f7799c82b1a9ddd74f08ab162fcb50acf9a491a5841f1d09931eec8145fa
7
+ data.tar.gz: 95c826339433a0a87f296676216e62b493cdc4d5b67ac73c400659194d3a54e874554d0431c3cbea02316d4265cd870755320ed5f5fd6b42722fdd17feba041e
data/config/default.yml CHANGED
@@ -453,6 +453,7 @@ Rails/InverseOf:
453
453
  Description: 'Checks for associations where the inverse cannot be determined automatically.'
454
454
  Enabled: true
455
455
  VersionAdded: '0.52'
456
+ IgnoreScopes: false
456
457
  Include:
457
458
  - app/models/**/*.rb
458
459
 
@@ -627,6 +628,7 @@ Rails/RedundantForeignKey:
627
628
  Rails/RedundantPresenceValidationOnBelongsTo:
628
629
  Description: 'Checks for redundant presence validation on belongs_to association.'
629
630
  Enabled: pending
631
+ SafeAutoCorrect: false
630
632
  VersionAdded: '2.13'
631
633
 
632
634
  Rails/RedundantReceiverInWithOptions:
@@ -702,15 +704,17 @@ Rails/ReversibleMigration:
702
704
  Reference: 'https://api.rubyonrails.org/classes/ActiveRecord/Migration/CommandRecorder.html'
703
705
  Enabled: true
704
706
  VersionAdded: '0.47'
707
+ VersionChanged: '2.13'
705
708
  Include:
706
- - db/migrate/*.rb
709
+ - db/**/*.rb
707
710
 
708
711
  Rails/ReversibleMigrationMethodDefinition:
709
712
  Description: 'Checks whether the migration implements either a `change` method or both an `up` and a `down` method.'
710
713
  Enabled: false
711
714
  VersionAdded: '2.10'
715
+ VersionChanged: '2.13'
712
716
  Include:
713
- - db/migrate/*.rb
717
+ - db/**/*.rb
714
718
 
715
719
  Rails/RootJoinChain:
716
720
  Description: 'Use a single `#join` instead of chaining on `Rails.root` or `Rails.public_path`.'
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # Common functionality for cops working with migrations
6
+ module MigrationsHelper
7
+ extend NodePattern::Macros
8
+
9
+ def_node_matcher :migration_class?, <<~PATTERN
10
+ (class
11
+ (const nil? _)
12
+ (send
13
+ (const (const {nil? cbase} :ActiveRecord) :Migration)
14
+ :[]
15
+ (float _))
16
+ _)
17
+ PATTERN
18
+
19
+ def in_migration?(node)
20
+ node.each_ancestor(:class).any? do |class_node|
21
+ migration_class?(class_node)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -10,25 +10,21 @@ module RuboCop
10
10
  # blank check of block arguments to the receiver object.
11
11
  #
12
12
  # For example, `[[1, 2], [3, nil]].reject { |first, second| second.blank? }` and
13
- # `[[1, 2], [3, nil]].compact_blank` are not compatible. The same is true for `empty?`.
13
+ # `[[1, 2], [3, nil]].compact_blank` are not compatible. The same is true for `blank?`.
14
14
  # This will work fine when the receiver is a hash object.
15
15
  #
16
16
  # @example
17
17
  #
18
18
  # # bad
19
19
  # collection.reject(&:blank?)
20
- # collection.reject(&:empty?)
21
20
  # collection.reject { |_k, v| v.blank? }
22
- # collection.reject { |_k, v| v.empty? }
23
21
  #
24
22
  # # good
25
23
  # collection.compact_blank
26
24
  #
27
25
  # # bad
28
26
  # collection.reject!(&:blank?)
29
- # collection.reject!(&:empty?)
30
27
  # collection.reject! { |_k, v| v.blank? }
31
- # collection.reject! { |_k, v| v.empty? }
32
28
  #
33
29
  # # good
34
30
  # collection.compact_blank!
@@ -48,13 +44,13 @@ module RuboCop
48
44
  (send _ {:reject :reject!})
49
45
  $(args ...)
50
46
  (send
51
- $(lvar _) {:blank? :empty?}))
47
+ $(lvar _) :blank?))
52
48
  PATTERN
53
49
 
54
50
  def_node_matcher :reject_with_block_pass?, <<~PATTERN
55
51
  (send _ {:reject :reject!}
56
52
  (block_pass
57
- (sym {:blank? :empty?})))
53
+ (sym :blank?)))
58
54
  PATTERN
59
55
 
60
56
  def on_send(node)
@@ -73,12 +69,17 @@ module RuboCop
73
69
  return true if reject_with_block_pass?(node)
74
70
 
75
71
  if (arguments, receiver_in_block = reject_with_block?(node.parent))
76
- return arguments.length == 1 || use_hash_value_block_argument?(arguments, receiver_in_block)
72
+ return use_single_value_block_argument?(arguments, receiver_in_block) ||
73
+ use_hash_value_block_argument?(arguments, receiver_in_block)
77
74
  end
78
75
 
79
76
  false
80
77
  end
81
78
 
79
+ def use_single_value_block_argument?(arguments, receiver_in_block)
80
+ arguments.length == 1 && arguments[0].source == receiver_in_block.source
81
+ end
82
+
82
83
  def use_hash_value_block_argument?(arguments, receiver_in_block)
83
84
  arguments.length == 2 && arguments[1].source == receiver_in_block.source
84
85
  end
@@ -26,7 +26,8 @@ module RuboCop
26
26
  RESTRICT_ON_SEND = %i[+ -].freeze
27
27
 
28
28
  DURATIONS = Set[:second, :seconds, :minute, :minutes, :hour, :hours,
29
- :day, :days, :week, :weeks, :fortnight, :fortnights]
29
+ :day, :days, :week, :weeks, :fortnight, :fortnights,
30
+ :month, :months, :year, :years]
30
31
 
31
32
  # @!method duration_arithmetic_argument?(node)
32
33
  # Match duration subtraction or addition with current time.
@@ -126,6 +126,18 @@ module RuboCop
126
126
  # has_many :physicians, through: :appointments
127
127
  # end
128
128
  #
129
+ # @example IgnoreScopes: false (default)
130
+ # # bad
131
+ # class Blog < ApplicationRecord
132
+ # has_many :posts, -> { order(published_at: :desc) }
133
+ # end
134
+ #
135
+ # @example IgnoreScopes: true
136
+ # # good
137
+ # class Blog < ApplicationRecord
138
+ # has_many :posts, -> { order(published_at: :desc) }
139
+ # end
140
+ #
129
141
  # @see https://guides.rubyonrails.org/association_basics.html#bi-directional-associations
130
142
  # @see https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#module-ActiveRecord::Associations::ClassMethods-label-Setting+Inverses
131
143
  class InverseOf < Base
@@ -189,7 +201,7 @@ module RuboCop
189
201
  end
190
202
 
191
203
  def scope?(arguments)
192
- arguments.any?(&:block_type?)
204
+ !ignore_scopes? && arguments.any?(&:block_type?)
193
205
  end
194
206
 
195
207
  def options_requiring_inverse_of?(options)
@@ -236,6 +248,10 @@ module RuboCop
236
248
  SPECIFY_MSG
237
249
  end
238
250
  end
251
+
252
+ def ignore_scopes?
253
+ cop_config['IgnoreScopes'] == true
254
+ end
239
255
  end
240
256
  end
241
257
  end
@@ -37,7 +37,7 @@ module RuboCop
37
37
  class ReadWriteAttribute < Base
38
38
  extend AutoCorrector
39
39
 
40
- MSG = 'Prefer `%<prefer>s` over `%<current>s`.'
40
+ MSG = 'Prefer `%<prefer>s`.'
41
41
  RESTRICT_ON_SEND = %i[read_attribute write_attribute].freeze
42
42
 
43
43
  def_node_matcher :read_write_attribute?, <<~PATTERN
@@ -51,35 +51,51 @@ module RuboCop
51
51
  return unless read_write_attribute?(node)
52
52
  return if within_shadowing_method?(node)
53
53
 
54
- add_offense(node.loc.selector, message: message(node)) do |corrector|
55
- case node.method_name
56
- when :read_attribute
57
- replacement = read_attribute_replacement(node)
58
- when :write_attribute
59
- replacement = write_attribute_replacement(node)
60
- end
61
-
62
- corrector.replace(node.source_range, replacement)
54
+ add_offense(node, message: build_message(node)) do |corrector|
55
+ corrector.replace(node.source_range, node_replacement(node))
63
56
  end
64
57
  end
65
58
 
66
59
  private
67
60
 
68
61
  def within_shadowing_method?(node)
69
- node.each_ancestor(:def).any? do |enclosing_method|
70
- shadowing_method_name = node.first_argument.value.to_s
71
- shadowing_method_name << '=' if node.method?(:write_attribute)
62
+ first_arg = node.first_argument
63
+ return false unless first_arg.respond_to?(:value)
64
+
65
+ enclosing_method = node.each_ancestor(:def).first
66
+ return false unless enclosing_method
72
67
 
73
- enclosing_method.method_name.to_s == shadowing_method_name
68
+ shadowing_method_name = first_arg.value.to_s
69
+ shadowing_method_name << '=' if node.method?(:write_attribute)
70
+ enclosing_method.method?(shadowing_method_name)
71
+ end
72
+
73
+ def build_message(node)
74
+ if node.single_line?
75
+ single_line_message(node)
76
+ else
77
+ multi_line_message(node)
74
78
  end
75
79
  end
76
80
 
77
- def message(node)
81
+ def single_line_message(node)
82
+ format(MSG, prefer: node_replacement(node))
83
+ end
84
+
85
+ def multi_line_message(node)
78
86
  if node.method?(:read_attribute)
79
- format(MSG, prefer: 'self[:attr]', current: 'read_attribute(:attr)')
87
+ format(MSG, prefer: 'self[:attr]')
80
88
  else
81
- format(MSG, prefer: 'self[:attr] = val',
82
- current: 'write_attribute(:attr, val)')
89
+ format(MSG, prefer: 'self[:attr] = val')
90
+ end
91
+ end
92
+
93
+ def node_replacement(node)
94
+ case node.method_name
95
+ when :read_attribute
96
+ read_attribute_replacement(node)
97
+ when :write_attribute
98
+ write_attribute_replacement(node)
83
99
  end
84
100
  end
85
101
 
@@ -8,6 +8,10 @@ module RuboCop
8
8
  # explicitly set to `false`. The presence validator is added
9
9
  # automatically, and explicit presence validation is redundant.
10
10
  #
11
+ # @safety
12
+ # This cop's autocorrection is unsafe because it changes the default error message
13
+ # from "can't be blank" to "must exist".
14
+ #
11
15
  # @example
12
16
  # # bad
13
17
  # belongs_to :user
@@ -46,9 +50,6 @@ module RuboCop
46
50
  # @example source that matches - by association
47
51
  # validates :name, :user, presence: true
48
52
  #
49
- # @example source that matches - with presence options
50
- # validates :user, presence: { message: 'duplicate' }
51
- #
52
53
  # @example source that matches - by a foreign key
53
54
  # validates :user_id, presence: true
54
55
  #
@@ -62,7 +63,7 @@ module RuboCop
62
63
  send nil? :validates
63
64
  (sym $_)+
64
65
  $[
65
- (hash <$(pair (sym :presence) {true hash}) ...>) # presence: true
66
+ (hash <$(pair (sym :presence) true) ...>) # presence: true
66
67
  !(hash <$(pair (sym :strict) {true const}) ...>) # strict: true
67
68
  ]
68
69
  )
@@ -176,6 +176,8 @@ module RuboCop
176
176
  #
177
177
  # @see https://api.rubyonrails.org/classes/ActiveRecord/Migration/CommandRecorder.html
178
178
  class ReversibleMigration < Base
179
+ include MigrationsHelper
180
+
179
181
  MSG = '%<action>s is not reversible.'
180
182
 
181
183
  def_node_matcher :irreversible_schema_statement_call, <<~PATTERN
@@ -207,7 +209,7 @@ module RuboCop
207
209
  PATTERN
208
210
 
209
211
  def on_send(node)
210
- return unless within_change_method?(node)
212
+ return unless in_migration?(node) && within_change_method?(node)
211
213
  return if within_reversible_or_up_only_block?(node)
212
214
 
213
215
  check_irreversible_schema_statement_node(node)
@@ -220,7 +222,7 @@ module RuboCop
220
222
  end
221
223
 
222
224
  def on_block(node)
223
- return unless within_change_method?(node)
225
+ return unless in_migration?(node) && within_change_method?(node)
224
226
  return if within_reversible_or_up_only_block?(node)
225
227
  return if node.body.nil?
226
228
 
@@ -43,19 +43,11 @@ module RuboCop
43
43
  # end
44
44
  # end
45
45
  class ReversibleMigrationMethodDefinition < Base
46
+ include MigrationsHelper
47
+
46
48
  MSG = 'Migrations must contain either a `change` method, or ' \
47
49
  'both an `up` and a `down` method.'
48
50
 
49
- def_node_matcher :migration_class?, <<~PATTERN
50
- (class
51
- (const nil? _)
52
- (send
53
- (const (const {nil? cbase} :ActiveRecord) :Migration)
54
- :[]
55
- (float _))
56
- _)
57
- PATTERN
58
-
59
51
  def_node_matcher :change_method?, <<~PATTERN
60
52
  [ #migration_class? `(def :change (args) _) ]
61
53
  PATTERN
@@ -4,6 +4,7 @@ require_relative 'mixin/active_record_helper'
4
4
  require_relative 'mixin/active_record_migrations_helper'
5
5
  require_relative 'mixin/enforce_superclass'
6
6
  require_relative 'mixin/index_method'
7
+ require_relative 'mixin/migrations_helper'
7
8
  require_relative 'mixin/target_rails_version'
8
9
 
9
10
  require_relative 'rails/action_filter'
@@ -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.13.1'
7
+ STRING = '2.13.2'
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.13.1
4
+ version: 2.13.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2022-01-09 00:00:00.000000000 Z
13
+ date: 2022-01-15 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -81,6 +81,7 @@ files:
81
81
  - lib/rubocop/cop/mixin/active_record_migrations_helper.rb
82
82
  - lib/rubocop/cop/mixin/enforce_superclass.rb
83
83
  - lib/rubocop/cop/mixin/index_method.rb
84
+ - lib/rubocop/cop/mixin/migrations_helper.rb
84
85
  - lib/rubocop/cop/mixin/target_rails_version.rb
85
86
  - lib/rubocop/cop/rails/action_filter.rb
86
87
  - lib/rubocop/cop/rails/active_record_aliases.rb