rubocop-rails 2.7.0 → 2.9.1

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 (95) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +16 -0
  3. data/config/default.yml +78 -4
  4. data/lib/rubocop/cop/mixin/active_record_helper.rb +5 -3
  5. data/lib/rubocop/cop/mixin/enforce_superclass.rb +40 -0
  6. data/lib/rubocop/cop/mixin/index_method.rb +25 -11
  7. data/lib/rubocop/cop/rails/action_filter.rb +10 -14
  8. data/lib/rubocop/cop/rails/active_record_aliases.rb +13 -17
  9. data/lib/rubocop/cop/rails/active_record_callbacks_order.rb +19 -16
  10. data/lib/rubocop/cop/rails/active_record_override.rb +1 -1
  11. data/lib/rubocop/cop/rails/active_support_aliases.rb +12 -21
  12. data/lib/rubocop/cop/rails/after_commit_override.rb +91 -0
  13. data/lib/rubocop/cop/rails/application_controller.rb +3 -7
  14. data/lib/rubocop/cop/rails/application_job.rb +2 -1
  15. data/lib/rubocop/cop/rails/application_mailer.rb +2 -7
  16. data/lib/rubocop/cop/rails/application_record.rb +2 -7
  17. data/lib/rubocop/cop/rails/arel_star.rb +41 -0
  18. data/lib/rubocop/cop/rails/assert_not.rb +8 -10
  19. data/lib/rubocop/cop/rails/attribute_default_block_value.rb +90 -0
  20. data/lib/rubocop/cop/rails/belongs_to.rb +9 -18
  21. data/lib/rubocop/cop/rails/blank.rb +27 -27
  22. data/lib/rubocop/cop/rails/bulk_change_table.rb +1 -1
  23. data/lib/rubocop/cop/rails/content_tag.rb +17 -17
  24. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +2 -1
  25. data/lib/rubocop/cop/rails/date.rb +10 -11
  26. data/lib/rubocop/cop/rails/default_scope.rb +11 -4
  27. data/lib/rubocop/cop/rails/delegate.rb +9 -9
  28. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +7 -8
  29. data/lib/rubocop/cop/rails/dynamic_find_by.rb +13 -11
  30. data/lib/rubocop/cop/rails/enum_hash.rb +11 -10
  31. data/lib/rubocop/cop/rails/enum_uniqueness.rb +2 -1
  32. data/lib/rubocop/cop/rails/environment_comparison.rb +18 -14
  33. data/lib/rubocop/cop/rails/exit.rb +4 -10
  34. data/lib/rubocop/cop/rails/file_path.rb +5 -4
  35. data/lib/rubocop/cop/rails/find_by.rb +13 -13
  36. data/lib/rubocop/cop/rails/find_by_id.rb +12 -21
  37. data/lib/rubocop/cop/rails/find_each.rb +17 -18
  38. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +3 -2
  39. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +4 -7
  40. data/lib/rubocop/cop/rails/helper_instance_variable.rb +30 -2
  41. data/lib/rubocop/cop/rails/http_positional_arguments.rb +25 -21
  42. data/lib/rubocop/cop/rails/http_status.rb +7 -9
  43. data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +8 -6
  44. data/lib/rubocop/cop/rails/index_by.rb +11 -2
  45. data/lib/rubocop/cop/rails/index_with.rb +11 -2
  46. data/lib/rubocop/cop/rails/inquiry.rb +7 -2
  47. data/lib/rubocop/cop/rails/inverse_of.rb +3 -2
  48. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +17 -15
  49. data/lib/rubocop/cop/rails/link_to_blank.rb +20 -22
  50. data/lib/rubocop/cop/rails/mailer_name.rb +19 -13
  51. data/lib/rubocop/cop/rails/match_route.rb +16 -13
  52. data/lib/rubocop/cop/rails/negate_include.rb +10 -8
  53. data/lib/rubocop/cop/rails/not_null_column.rb +2 -1
  54. data/lib/rubocop/cop/rails/order_by_id.rb +52 -0
  55. data/lib/rubocop/cop/rails/output.rb +5 -2
  56. data/lib/rubocop/cop/rails/output_safety.rb +3 -2
  57. data/lib/rubocop/cop/rails/pick.rb +14 -12
  58. data/lib/rubocop/cop/rails/pluck.rb +6 -9
  59. data/lib/rubocop/cop/rails/pluck_id.rb +4 -6
  60. data/lib/rubocop/cop/rails/pluck_in_where.rb +39 -5
  61. data/lib/rubocop/cop/rails/pluralization_grammar.rb +10 -14
  62. data/lib/rubocop/cop/rails/presence.rb +12 -13
  63. data/lib/rubocop/cop/rails/present.rb +30 -24
  64. data/lib/rubocop/cop/rails/rake_environment.rb +9 -11
  65. data/lib/rubocop/cop/rails/read_write_attribute.rb +12 -11
  66. data/lib/rubocop/cop/rails/redundant_allow_nil.rb +29 -31
  67. data/lib/rubocop/cop/rails/redundant_foreign_key.rb +9 -12
  68. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +11 -10
  69. data/lib/rubocop/cop/rails/reflection_class_name.rb +4 -3
  70. data/lib/rubocop/cop/rails/refute_methods.rb +9 -10
  71. data/lib/rubocop/cop/rails/relative_date_constant.rb +20 -9
  72. data/lib/rubocop/cop/rails/render_inline.rb +5 -12
  73. data/lib/rubocop/cop/rails/render_plain_text.rb +9 -14
  74. data/lib/rubocop/cop/rails/request_referer.rb +7 -7
  75. data/lib/rubocop/cop/rails/reversible_migration.rb +82 -7
  76. data/lib/rubocop/cop/rails/safe_navigation.rb +11 -10
  77. data/lib/rubocop/cop/rails/safe_navigation_with_blank.rb +5 -10
  78. data/lib/rubocop/cop/rails/save_bang.rb +19 -22
  79. data/lib/rubocop/cop/rails/scope_args.rb +2 -1
  80. data/lib/rubocop/cop/rails/short_i18n.rb +7 -9
  81. data/lib/rubocop/cop/rails/skips_model_validations.rb +4 -4
  82. data/lib/rubocop/cop/rails/squished_sql_heredocs.rb +82 -0
  83. data/lib/rubocop/cop/rails/time_zone.rb +22 -20
  84. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +6 -6
  85. data/lib/rubocop/cop/rails/unique_validation_without_index.rb +18 -8
  86. data/lib/rubocop/cop/rails/unknown_env.rb +15 -4
  87. data/lib/rubocop/cop/rails/validation.rb +15 -14
  88. data/lib/rubocop/cop/rails/where_equals.rb +98 -0
  89. data/lib/rubocop/cop/rails/where_exists.rb +74 -16
  90. data/lib/rubocop/cop/rails/where_not.rb +97 -0
  91. data/lib/rubocop/cop/rails_cops.rb +8 -0
  92. data/lib/rubocop/rails/schema_loader.rb +4 -4
  93. data/lib/rubocop/rails/schema_loader/schema.rb +5 -5
  94. data/lib/rubocop/rails/version.rb +5 -1
  95. metadata +23 -9
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Rails
6
+ # This cop identifies places where manually constructed SQL
7
+ # in `where` can be replaced with `where.not(...)`.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # User.where('name != ?', 'Gabe')
12
+ # User.where('name != :name', name: 'Gabe')
13
+ # User.where('name <> ?', 'Gabe')
14
+ # User.where('name <> :name', name: 'Gabe')
15
+ # User.where('name IS NOT NULL')
16
+ # User.where('name NOT IN (?)', ['john', 'jane'])
17
+ # User.where('name NOT IN (:names)', names: ['john', 'jane'])
18
+ #
19
+ # # good
20
+ # User.where.not(name: 'Gabe')
21
+ # User.where.not(name: nil)
22
+ # User.where.not(name: ['john', 'jane'])
23
+ #
24
+ class WhereNot < Base
25
+ include RangeHelp
26
+ extend AutoCorrector
27
+
28
+ MSG = 'Use `%<good_method>s` instead of manually constructing negated SQL in `where`.'
29
+ RESTRICT_ON_SEND = %i[where].freeze
30
+
31
+ def_node_matcher :where_method_call?, <<~PATTERN
32
+ {
33
+ (send _ :where (array $str_type? $_ ?))
34
+ (send _ :where $str_type? $_ ?)
35
+ }
36
+ PATTERN
37
+
38
+ def on_send(node)
39
+ where_method_call?(node) do |template_node, value_node|
40
+ value_node = value_node.first
41
+
42
+ range = offense_range(node)
43
+
44
+ column_and_value = extract_column_and_value(template_node, value_node)
45
+ return unless column_and_value
46
+
47
+ good_method = build_good_method(*column_and_value)
48
+ message = format(MSG, good_method: good_method)
49
+
50
+ add_offense(range, message: message) do |corrector|
51
+ corrector.replace(range, good_method)
52
+ end
53
+ end
54
+ end
55
+
56
+ NOT_EQ_ANONYMOUS_RE = /\A([\w.]+)\s+(?:!=|<>)\s+\?\z/.freeze # column != ?, column <> ?
57
+ NOT_IN_ANONYMOUS_RE = /\A([\w.]+)\s+NOT\s+IN\s+\(\?\)\z/i.freeze # column NOT IN (?)
58
+ NOT_EQ_NAMED_RE = /\A([\w.]+)\s+(?:!=|<>)\s+:(\w+)\z/.freeze # column != :column, column <> :column
59
+ NOT_IN_NAMED_RE = /\A([\w.]+)\s+NOT\s+IN\s+\(:(\w+)\)\z/i.freeze # column NOT IN (:column)
60
+ IS_NOT_NULL_RE = /\A([\w.]+)\s+IS\s+NOT\s+NULL\z/i.freeze # column IS NOT NULL
61
+
62
+ private
63
+
64
+ def offense_range(node)
65
+ range_between(node.loc.selector.begin_pos, node.loc.expression.end_pos)
66
+ end
67
+
68
+ def extract_column_and_value(template_node, value_node)
69
+ value =
70
+ case template_node.value
71
+ when NOT_EQ_ANONYMOUS_RE, NOT_IN_ANONYMOUS_RE
72
+ value_node.source
73
+ when NOT_EQ_NAMED_RE, NOT_IN_NAMED_RE
74
+ return unless value_node.hash_type?
75
+
76
+ pair = value_node.pairs.find { |p| p.key.value.to_sym == Regexp.last_match(2).to_sym }
77
+ pair.value.source
78
+ when IS_NOT_NULL_RE
79
+ 'nil'
80
+ else
81
+ return
82
+ end
83
+
84
+ [Regexp.last_match(1), value]
85
+ end
86
+
87
+ def build_good_method(column, value)
88
+ if column.include?('.')
89
+ "where.not('#{column}' => #{value})"
90
+ else
91
+ "where.not(#{column}: #{value})"
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'mixin/active_record_helper'
4
+ require_relative 'mixin/enforce_superclass'
4
5
  require_relative 'mixin/index_method'
5
6
  require_relative 'mixin/target_rails_version'
6
7
 
@@ -9,11 +10,14 @@ require_relative 'rails/active_record_aliases'
9
10
  require_relative 'rails/active_record_callbacks_order'
10
11
  require_relative 'rails/active_record_override'
11
12
  require_relative 'rails/active_support_aliases'
13
+ require_relative 'rails/after_commit_override'
12
14
  require_relative 'rails/application_controller'
13
15
  require_relative 'rails/application_job'
14
16
  require_relative 'rails/application_mailer'
15
17
  require_relative 'rails/application_record'
18
+ require_relative 'rails/arel_star'
16
19
  require_relative 'rails/assert_not'
20
+ require_relative 'rails/attribute_default_block_value'
17
21
  require_relative 'rails/belongs_to'
18
22
  require_relative 'rails/blank'
19
23
  require_relative 'rails/bulk_change_table'
@@ -48,6 +52,7 @@ require_relative 'rails/mailer_name'
48
52
  require_relative 'rails/match_route'
49
53
  require_relative 'rails/negate_include'
50
54
  require_relative 'rails/not_null_column'
55
+ require_relative 'rails/order_by_id'
51
56
  require_relative 'rails/output'
52
57
  require_relative 'rails/output_safety'
53
58
  require_relative 'rails/pick'
@@ -75,9 +80,12 @@ require_relative 'rails/save_bang'
75
80
  require_relative 'rails/scope_args'
76
81
  require_relative 'rails/short_i18n'
77
82
  require_relative 'rails/skips_model_validations'
83
+ require_relative 'rails/squished_sql_heredocs'
78
84
  require_relative 'rails/time_zone'
79
85
  require_relative 'rails/uniq_before_pluck'
80
86
  require_relative 'rails/unique_validation_without_index'
81
87
  require_relative 'rails/unknown_env'
82
88
  require_relative 'rails/validation'
89
+ require_relative 'rails/where_equals'
83
90
  require_relative 'rails/where_exists'
91
+ require_relative 'rails/where_not'
@@ -13,15 +13,15 @@ module RuboCop
13
13
  #
14
14
  # @return [Schema, nil]
15
15
  def load(target_ruby_version)
16
- return @schema if defined?(@schema)
16
+ return @load if defined?(@load)
17
17
 
18
- @schema = load!(target_ruby_version)
18
+ @load = load!(target_ruby_version)
19
19
  end
20
20
 
21
21
  def reset!
22
- return unless instance_variable_defined?(:@schema)
22
+ return unless instance_variable_defined?(:@load)
23
23
 
24
- remove_instance_variable(:@schema)
24
+ remove_instance_variable(:@load)
25
25
  end
26
26
 
27
27
  def db_schema_path
@@ -97,14 +97,12 @@ module RuboCop
97
97
  end.compact
98
98
  end
99
99
 
100
- def each_content(node)
101
- return enum_for(__method__, node) unless block_given?
100
+ def each_content(node, &block)
101
+ return enum_for(__method__, node) unless block
102
102
 
103
103
  case node.body&.type
104
104
  when :begin
105
- node.body.children.each do |child|
106
- yield(child)
107
- end
105
+ node.body.children.each(&block)
108
106
  else
109
107
  yield(node.body)
110
108
  end
@@ -178,6 +176,8 @@ module RuboCop
178
176
  attr_reader :table_name
179
177
 
180
178
  def initialize(node)
179
+ super(node)
180
+
181
181
  @table_name = node.first_argument.value
182
182
  @columns, @expression = build_columns_or_expr(node.arguments[1])
183
183
  @unique = nil
@@ -4,7 +4,11 @@ module RuboCop
4
4
  module Rails
5
5
  # This module holds the RuboCop Rails version information.
6
6
  module Version
7
- STRING = '2.7.0'
7
+ STRING = '2.9.1'
8
+
9
+ def self.document_version
10
+ STRING.match('\d+\.\d+').to_s
11
+ end
8
12
  end
9
13
  end
10
14
  end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.0
4
+ version: 2.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
8
8
  - Jonas Arvidsson
9
9
  - Yuji Nakayama
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-07-20 00:00:00.000000000 Z
13
+ date: 2020-12-16 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -46,14 +46,20 @@ dependencies:
46
46
  requirements:
47
47
  - - ">="
48
48
  - !ruby/object:Gem::Version
49
- version: 0.87.0
49
+ version: 0.90.0
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: '2.0'
50
53
  type: :runtime
51
54
  prerelease: false
52
55
  version_requirements: !ruby/object:Gem::Requirement
53
56
  requirements:
54
57
  - - ">="
55
58
  - !ruby/object:Gem::Version
56
- version: 0.87.0
59
+ version: 0.90.0
60
+ - - "<"
61
+ - !ruby/object:Gem::Version
62
+ version: '2.0'
57
63
  description: |
58
64
  Automatic Rails code style checking tool.
59
65
  A RuboCop extension focused on enforcing Rails best practices and coding conventions.
@@ -70,6 +76,7 @@ files:
70
76
  - config/default.yml
71
77
  - lib/rubocop-rails.rb
72
78
  - lib/rubocop/cop/mixin/active_record_helper.rb
79
+ - lib/rubocop/cop/mixin/enforce_superclass.rb
73
80
  - lib/rubocop/cop/mixin/index_method.rb
74
81
  - lib/rubocop/cop/mixin/target_rails_version.rb
75
82
  - lib/rubocop/cop/rails/action_filter.rb
@@ -77,11 +84,14 @@ files:
77
84
  - lib/rubocop/cop/rails/active_record_callbacks_order.rb
78
85
  - lib/rubocop/cop/rails/active_record_override.rb
79
86
  - lib/rubocop/cop/rails/active_support_aliases.rb
87
+ - lib/rubocop/cop/rails/after_commit_override.rb
80
88
  - lib/rubocop/cop/rails/application_controller.rb
81
89
  - lib/rubocop/cop/rails/application_job.rb
82
90
  - lib/rubocop/cop/rails/application_mailer.rb
83
91
  - lib/rubocop/cop/rails/application_record.rb
92
+ - lib/rubocop/cop/rails/arel_star.rb
84
93
  - lib/rubocop/cop/rails/assert_not.rb
94
+ - lib/rubocop/cop/rails/attribute_default_block_value.rb
85
95
  - lib/rubocop/cop/rails/belongs_to.rb
86
96
  - lib/rubocop/cop/rails/blank.rb
87
97
  - lib/rubocop/cop/rails/bulk_change_table.rb
@@ -116,6 +126,7 @@ files:
116
126
  - lib/rubocop/cop/rails/match_route.rb
117
127
  - lib/rubocop/cop/rails/negate_include.rb
118
128
  - lib/rubocop/cop/rails/not_null_column.rb
129
+ - lib/rubocop/cop/rails/order_by_id.rb
119
130
  - lib/rubocop/cop/rails/output.rb
120
131
  - lib/rubocop/cop/rails/output_safety.rb
121
132
  - lib/rubocop/cop/rails/pick.rb
@@ -143,12 +154,15 @@ files:
143
154
  - lib/rubocop/cop/rails/scope_args.rb
144
155
  - lib/rubocop/cop/rails/short_i18n.rb
145
156
  - lib/rubocop/cop/rails/skips_model_validations.rb
157
+ - lib/rubocop/cop/rails/squished_sql_heredocs.rb
146
158
  - lib/rubocop/cop/rails/time_zone.rb
147
159
  - lib/rubocop/cop/rails/uniq_before_pluck.rb
148
160
  - lib/rubocop/cop/rails/unique_validation_without_index.rb
149
161
  - lib/rubocop/cop/rails/unknown_env.rb
150
162
  - lib/rubocop/cop/rails/validation.rb
163
+ - lib/rubocop/cop/rails/where_equals.rb
151
164
  - lib/rubocop/cop/rails/where_exists.rb
165
+ - lib/rubocop/cop/rails/where_not.rb
152
166
  - lib/rubocop/cop/rails_cops.rb
153
167
  - lib/rubocop/rails.rb
154
168
  - lib/rubocop/rails/inject.rb
@@ -162,9 +176,9 @@ metadata:
162
176
  homepage_uri: https://docs.rubocop.org/rubocop-rails/
163
177
  changelog_uri: https://github.com/rubocop-hq/rubocop-rails/blob/master/CHANGELOG.md
164
178
  source_code_uri: https://github.com/rubocop-hq/rubocop-rails/
165
- documentation_uri: https://docs.rubocop.org/rubocop-rails/
179
+ documentation_uri: https://docs.rubocop.org/rubocop-rails/2.9/
166
180
  bug_tracker_uri: https://github.com/rubocop-hq/rubocop-rails/issues
167
- post_install_message:
181
+ post_install_message:
168
182
  rdoc_options: []
169
183
  require_paths:
170
184
  - lib
@@ -179,8 +193,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
179
193
  - !ruby/object:Gem::Version
180
194
  version: '0'
181
195
  requirements: []
182
- rubygems_version: 3.1.4
183
- signing_key:
196
+ rubygems_version: 3.2.1
197
+ signing_key:
184
198
  specification_version: 4
185
199
  summary: Automatic Rails code style checking tool.
186
200
  test_files: []