rubocop-rails 2.15.2 → 2.16.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.
- checksums.yaml +4 -4
- data/config/default.yml +81 -0
- data/config/obsoletion.yml +10 -0
- data/lib/rubocop/cop/mixin/active_record_helper.rb +1 -4
- data/lib/rubocop/cop/mixin/active_record_migrations_helper.rb +1 -3
- data/lib/rubocop/cop/mixin/index_method.rb +5 -15
- data/lib/rubocop/cop/rails/action_controller_flash_before_render.rb +98 -0
- data/lib/rubocop/cop/rails/action_filter.rb +1 -1
- data/lib/rubocop/cop/rails/active_record_aliases.rb +1 -4
- data/lib/rubocop/cop/rails/active_record_override.rb +2 -5
- data/lib/rubocop/cop/rails/active_support_on_load.rb +70 -0
- data/lib/rubocop/cop/rails/add_column_index.rb +1 -4
- data/lib/rubocop/cop/rails/blank.rb +1 -2
- data/lib/rubocop/cop/rails/bulk_change_table.rb +6 -20
- data/lib/rubocop/cop/rails/compact_blank.rb +5 -1
- data/lib/rubocop/cop/rails/content_tag.rb +1 -3
- data/lib/rubocop/cop/rails/date.rb +4 -9
- data/lib/rubocop/cop/rails/delegate.rb +2 -5
- data/lib/rubocop/cop/rails/deprecated_active_model_errors_methods.rb +17 -13
- data/lib/rubocop/cop/rails/dot_separated_keys.rb +1 -1
- data/lib/rubocop/cop/rails/dynamic_find_by.rb +2 -4
- data/lib/rubocop/cop/rails/enum_uniqueness.rb +2 -5
- data/lib/rubocop/cop/rails/environment_comparison.rb +1 -2
- data/lib/rubocop/cop/rails/file_path.rb +2 -4
- data/lib/rubocop/cop/rails/find_each.rb +8 -2
- data/lib/rubocop/cop/rails/freeze_time.rb +74 -0
- data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +1 -3
- data/lib/rubocop/cop/rails/http_positional_arguments.rb +4 -9
- data/lib/rubocop/cop/rails/http_status.rb +5 -10
- data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +3 -10
- data/lib/rubocop/cop/rails/inverse_of.rb +3 -6
- data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +2 -6
- data/lib/rubocop/cop/rails/link_to_blank.rb +1 -4
- data/lib/rubocop/cop/rails/output.rb +2 -5
- data/lib/rubocop/cop/rails/pluralization_grammar.rb +1 -2
- data/lib/rubocop/cop/rails/presence.rb +1 -3
- data/lib/rubocop/cop/rails/present.rb +3 -6
- data/lib/rubocop/cop/rails/rake_environment.rb +1 -1
- data/lib/rubocop/cop/rails/redundant_allow_nil.rb +2 -4
- data/lib/rubocop/cop/rails/redundant_foreign_key.rb +1 -1
- data/lib/rubocop/cop/rails/redundant_presence_validation_on_belongs_to.rb +2 -2
- data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +28 -26
- data/lib/rubocop/cop/rails/reflection_class_name.rb +17 -0
- data/lib/rubocop/cop/rails/refute_methods.rb +1 -5
- data/lib/rubocop/cop/rails/relative_date_constant.rb +2 -5
- data/lib/rubocop/cop/rails/request_referer.rb +1 -2
- data/lib/rubocop/cop/rails/reversible_migration.rb +10 -33
- data/lib/rubocop/cop/rails/reversible_migration_method_definition.rb +1 -2
- data/lib/rubocop/cop/rails/root_pathname_methods.rb +214 -0
- data/lib/rubocop/cop/rails/safe_navigation_with_blank.rb +1 -3
- data/lib/rubocop/cop/rails/save_bang.rb +10 -22
- data/lib/rubocop/cop/rails/short_i18n.rb +1 -4
- data/lib/rubocop/cop/rails/skips_model_validations.rb +1 -2
- data/lib/rubocop/cop/rails/squished_sql_heredocs.rb +1 -5
- data/lib/rubocop/cop/rails/time_zone.rb +8 -19
- data/lib/rubocop/cop/rails/to_s_with_argument.rb +41 -0
- data/lib/rubocop/cop/rails/top_level_hash_with_indifferent_access.rb +49 -0
- data/lib/rubocop/cop/rails/uniq_before_pluck.rb +3 -6
- data/lib/rubocop/cop/rails/unique_validation_without_index.rb +1 -3
- data/lib/rubocop/cop/rails/unknown_env.rb +2 -4
- data/lib/rubocop/cop/rails/validation.rb +4 -12
- data/lib/rubocop/cop/rails/where_missing.rb +111 -0
- data/lib/rubocop/cop/rails_cops.rb +7 -0
- data/lib/rubocop/rails/version.rb +1 -1
- metadata +13 -8
- data/bin/console +0 -11
- data/bin/setup +0 -7
@@ -19,8 +19,7 @@ module RuboCop
|
|
19
19
|
# Rails.env == 'production'
|
20
20
|
class UnknownEnv < Base
|
21
21
|
MSG = 'Unknown environment `%<name>s`.'
|
22
|
-
MSG_SIMILAR = 'Unknown environment `%<name>s`. '
|
23
|
-
'Did you mean `%<similar>s`?'
|
22
|
+
MSG_SIMILAR = 'Unknown environment `%<name>s`. Did you mean `%<similar>s`?'
|
24
23
|
|
25
24
|
def_node_matcher :rails_env?, <<~PATTERN
|
26
25
|
(send
|
@@ -79,8 +78,7 @@ module RuboCop
|
|
79
78
|
|
80
79
|
def unknown_env_predicate?(name)
|
81
80
|
name = name.to_s
|
82
|
-
name.end_with?('?') &&
|
83
|
-
!environments.include?(name[0..-2])
|
81
|
+
name.end_with?('?') && !environments.include?(name[0..-2])
|
84
82
|
end
|
85
83
|
|
86
84
|
def unknown_env_name?(name)
|
@@ -35,8 +35,7 @@ module RuboCop
|
|
35
35
|
class Validation < Base
|
36
36
|
extend AutoCorrector
|
37
37
|
|
38
|
-
MSG = 'Prefer the new style validations `%<prefer>s` over '
|
39
|
-
'`%<current>s`.'
|
38
|
+
MSG = 'Prefer the new style validations `%<prefer>s` over `%<current>s`.'
|
40
39
|
|
41
40
|
TYPES = %w[
|
42
41
|
acceptance
|
@@ -62,8 +61,7 @@ module RuboCop
|
|
62
61
|
|
63
62
|
add_offense(range, message: message(node)) do |corrector|
|
64
63
|
last_argument = node.arguments.last
|
65
|
-
return if !last_argument.literal? && !last_argument.splat_type? &&
|
66
|
-
!frozen_array_argument?(last_argument)
|
64
|
+
return if !last_argument.literal? && !last_argument.splat_type? && !frozen_array_argument?(last_argument)
|
67
65
|
|
68
66
|
corrector.replace(range, 'validates')
|
69
67
|
correct_validate_type(corrector, node)
|
@@ -104,10 +102,7 @@ module RuboCop
|
|
104
102
|
end
|
105
103
|
|
106
104
|
def correct_validate_type_for_hash(corrector, node, arguments)
|
107
|
-
corrector.replace(
|
108
|
-
arguments.loc.expression,
|
109
|
-
"#{validate_type(node)}: #{braced_options(arguments)}"
|
110
|
-
)
|
105
|
+
corrector.replace(arguments.loc.expression, "#{validate_type(node)}: #{braced_options(arguments)}")
|
111
106
|
end
|
112
107
|
|
113
108
|
def correct_validate_type_for_array(corrector, node, arguments, loc)
|
@@ -121,10 +116,7 @@ module RuboCop
|
|
121
116
|
end
|
122
117
|
end
|
123
118
|
|
124
|
-
corrector.replace(
|
125
|
-
loc.expression,
|
126
|
-
"#{attributes.join(', ')}, #{validate_type(node)}: true"
|
127
|
-
)
|
119
|
+
corrector.replace(loc.expression, "#{attributes.join(', ')}, #{validate_type(node)}: true")
|
128
120
|
end
|
129
121
|
|
130
122
|
def validate_type(node)
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Rails
|
6
|
+
# Use `where.missing(...)` to find missing relationship records.
|
7
|
+
#
|
8
|
+
# This cop is enabled in Rails 6.1 or higher.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# # bad
|
12
|
+
# Post.left_joins(:author).where(authors: { id: nil })
|
13
|
+
#
|
14
|
+
# # good
|
15
|
+
# Post.where.missing(:author)
|
16
|
+
#
|
17
|
+
class WhereMissing < Base
|
18
|
+
include RangeHelp
|
19
|
+
extend AutoCorrector
|
20
|
+
extend TargetRailsVersion
|
21
|
+
|
22
|
+
MSG = 'Use `where.missing(:%<left_joins_association>s)` instead of ' \
|
23
|
+
'`%<left_joins_method>s(:%<left_joins_association>s).where(%<where_association>s: { id: nil })`.'
|
24
|
+
RESTRICT_ON_SEND = %i[left_joins left_outer_joins].freeze
|
25
|
+
|
26
|
+
minimum_target_rails_version 6.1
|
27
|
+
|
28
|
+
# @!method where_node_and_argument(node)
|
29
|
+
def_node_search :where_node_and_argument, <<~PATTERN
|
30
|
+
$(send ... :where (hash <(pair $(sym _) (hash (pair (sym :id) (nil))))...> ))
|
31
|
+
PATTERN
|
32
|
+
|
33
|
+
# @!method missing_relationship(node)
|
34
|
+
def_node_search :missing_relationship, <<~PATTERN
|
35
|
+
(pair (sym _) (hash (pair (sym :id) (nil))))
|
36
|
+
PATTERN
|
37
|
+
|
38
|
+
def on_send(node)
|
39
|
+
return unless node.first_argument.sym_type?
|
40
|
+
|
41
|
+
where_node_and_argument(root_receiver(node)) do |where_node, where_argument|
|
42
|
+
next unless same_relationship?(where_argument, node.first_argument)
|
43
|
+
|
44
|
+
range = range_between(node.loc.selector.begin_pos, node.loc.expression.end_pos)
|
45
|
+
register_offense(node, where_node, where_argument, range)
|
46
|
+
break
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def root_receiver(node)
|
53
|
+
node&.parent&.send_type? ? root_receiver(node.parent) : node
|
54
|
+
end
|
55
|
+
|
56
|
+
def same_relationship?(where, left_joins)
|
57
|
+
where.value.to_s.match?(/^#{left_joins.value}s?$/)
|
58
|
+
end
|
59
|
+
|
60
|
+
def register_offense(node, where_node, where_argument, range)
|
61
|
+
add_offense(range, message: message(node, where_argument)) do |corrector|
|
62
|
+
corrector.replace(node.loc.selector, 'where.missing')
|
63
|
+
if multi_condition?(where_node.first_argument)
|
64
|
+
replace_where_method(corrector, where_node)
|
65
|
+
else
|
66
|
+
remove_where_method(corrector, node, where_node)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def replace_where_method(corrector, where_node)
|
72
|
+
missing_relationship(where_node) do |where_clause|
|
73
|
+
corrector.remove(replace_range(where_clause))
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def replace_range(child)
|
78
|
+
if (right_sibling = child.right_sibling)
|
79
|
+
range_between(child.loc.expression.begin_pos, right_sibling.loc.expression.begin_pos)
|
80
|
+
else
|
81
|
+
range_between(child.left_sibling.loc.expression.end_pos, child.loc.expression.end_pos)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def remove_where_method(corrector, node, where_node)
|
86
|
+
range = range_between(where_node.loc.selector.begin_pos, where_node.loc.end.end_pos)
|
87
|
+
if node.multiline? && !same_line?(node, where_node)
|
88
|
+
range = range_by_whole_lines(range, include_final_newline: true)
|
89
|
+
else
|
90
|
+
corrector.remove(where_node.loc.dot)
|
91
|
+
end
|
92
|
+
|
93
|
+
corrector.remove(range)
|
94
|
+
end
|
95
|
+
|
96
|
+
def same_line?(left_joins_node, where_node)
|
97
|
+
left_joins_node.loc.selector.line == where_node.loc.selector.line
|
98
|
+
end
|
99
|
+
|
100
|
+
def multi_condition?(where_arg)
|
101
|
+
where_arg.children.count > 1
|
102
|
+
end
|
103
|
+
|
104
|
+
def message(node, where_argument)
|
105
|
+
format(MSG, left_joins_association: node.first_argument.value, left_joins_method: node.method_name,
|
106
|
+
where_association: where_argument.value)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -8,12 +8,14 @@ require_relative 'mixin/index_method'
|
|
8
8
|
require_relative 'mixin/migrations_helper'
|
9
9
|
require_relative 'mixin/target_rails_version'
|
10
10
|
|
11
|
+
require_relative 'rails/action_controller_flash_before_render'
|
11
12
|
require_relative 'rails/action_controller_test_case'
|
12
13
|
require_relative 'rails/action_filter'
|
13
14
|
require_relative 'rails/active_record_aliases'
|
14
15
|
require_relative 'rails/active_record_callbacks_order'
|
15
16
|
require_relative 'rails/active_record_override'
|
16
17
|
require_relative 'rails/active_support_aliases'
|
18
|
+
require_relative 'rails/active_support_on_load'
|
17
19
|
require_relative 'rails/add_column_index'
|
18
20
|
require_relative 'rails/after_commit_override'
|
19
21
|
require_relative 'rails/application_controller'
|
@@ -50,6 +52,7 @@ require_relative 'rails/file_path'
|
|
50
52
|
require_relative 'rails/find_by'
|
51
53
|
require_relative 'rails/find_by_id'
|
52
54
|
require_relative 'rails/find_each'
|
55
|
+
require_relative 'rails/freeze_time'
|
53
56
|
require_relative 'rails/has_and_belongs_to_many'
|
54
57
|
require_relative 'rails/has_many_or_has_one_dependent'
|
55
58
|
require_relative 'rails/helper_instance_variable'
|
@@ -97,6 +100,7 @@ require_relative 'rails/require_dependency'
|
|
97
100
|
require_relative 'rails/reversible_migration'
|
98
101
|
require_relative 'rails/reversible_migration_method_definition'
|
99
102
|
require_relative 'rails/root_join_chain'
|
103
|
+
require_relative 'rails/root_pathname_methods'
|
100
104
|
require_relative 'rails/root_public_path'
|
101
105
|
require_relative 'rails/safe_navigation'
|
102
106
|
require_relative 'rails/safe_navigation_with_blank'
|
@@ -111,6 +115,8 @@ require_relative 'rails/table_name_assignment'
|
|
111
115
|
require_relative 'rails/time_zone'
|
112
116
|
require_relative 'rails/time_zone_assignment'
|
113
117
|
require_relative 'rails/to_formatted_s'
|
118
|
+
require_relative 'rails/to_s_with_argument'
|
119
|
+
require_relative 'rails/top_level_hash_with_indifferent_access'
|
114
120
|
require_relative 'rails/transaction_exit_statement'
|
115
121
|
require_relative 'rails/uniq_before_pluck'
|
116
122
|
require_relative 'rails/unique_validation_without_index'
|
@@ -119,4 +125,5 @@ require_relative 'rails/unused_ignored_columns'
|
|
119
125
|
require_relative 'rails/validation'
|
120
126
|
require_relative 'rails/where_equals'
|
121
127
|
require_relative 'rails/where_exists'
|
128
|
+
require_relative 'rails/where_missing'
|
122
129
|
require_relative 'rails/where_not'
|
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.
|
4
|
+
version: 2.16.1
|
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-
|
13
|
+
date: 2022-09-17 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
@@ -46,7 +46,7 @@ dependencies:
|
|
46
46
|
requirements:
|
47
47
|
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: 1.
|
49
|
+
version: 1.33.0
|
50
50
|
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
52
|
version: '2.0'
|
@@ -56,7 +56,7 @@ dependencies:
|
|
56
56
|
requirements:
|
57
57
|
- - ">="
|
58
58
|
- !ruby/object:Gem::Version
|
59
|
-
version: 1.
|
59
|
+
version: 1.33.0
|
60
60
|
- - "<"
|
61
61
|
- !ruby/object:Gem::Version
|
62
62
|
version: '2.0'
|
@@ -72,8 +72,6 @@ extra_rdoc_files:
|
|
72
72
|
files:
|
73
73
|
- LICENSE.txt
|
74
74
|
- README.md
|
75
|
-
- bin/console
|
76
|
-
- bin/setup
|
77
75
|
- config/default.yml
|
78
76
|
- config/obsoletion.yml
|
79
77
|
- lib/rubocop-rails.rb
|
@@ -84,12 +82,14 @@ files:
|
|
84
82
|
- lib/rubocop/cop/mixin/index_method.rb
|
85
83
|
- lib/rubocop/cop/mixin/migrations_helper.rb
|
86
84
|
- lib/rubocop/cop/mixin/target_rails_version.rb
|
85
|
+
- lib/rubocop/cop/rails/action_controller_flash_before_render.rb
|
87
86
|
- lib/rubocop/cop/rails/action_controller_test_case.rb
|
88
87
|
- lib/rubocop/cop/rails/action_filter.rb
|
89
88
|
- lib/rubocop/cop/rails/active_record_aliases.rb
|
90
89
|
- lib/rubocop/cop/rails/active_record_callbacks_order.rb
|
91
90
|
- lib/rubocop/cop/rails/active_record_override.rb
|
92
91
|
- lib/rubocop/cop/rails/active_support_aliases.rb
|
92
|
+
- lib/rubocop/cop/rails/active_support_on_load.rb
|
93
93
|
- lib/rubocop/cop/rails/add_column_index.rb
|
94
94
|
- lib/rubocop/cop/rails/after_commit_override.rb
|
95
95
|
- lib/rubocop/cop/rails/application_controller.rb
|
@@ -126,6 +126,7 @@ files:
|
|
126
126
|
- lib/rubocop/cop/rails/find_by.rb
|
127
127
|
- lib/rubocop/cop/rails/find_by_id.rb
|
128
128
|
- lib/rubocop/cop/rails/find_each.rb
|
129
|
+
- lib/rubocop/cop/rails/freeze_time.rb
|
129
130
|
- lib/rubocop/cop/rails/has_and_belongs_to_many.rb
|
130
131
|
- lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb
|
131
132
|
- lib/rubocop/cop/rails/helper_instance_variable.rb
|
@@ -173,6 +174,7 @@ files:
|
|
173
174
|
- lib/rubocop/cop/rails/reversible_migration.rb
|
174
175
|
- lib/rubocop/cop/rails/reversible_migration_method_definition.rb
|
175
176
|
- lib/rubocop/cop/rails/root_join_chain.rb
|
177
|
+
- lib/rubocop/cop/rails/root_pathname_methods.rb
|
176
178
|
- lib/rubocop/cop/rails/root_public_path.rb
|
177
179
|
- lib/rubocop/cop/rails/safe_navigation.rb
|
178
180
|
- lib/rubocop/cop/rails/safe_navigation_with_blank.rb
|
@@ -187,6 +189,8 @@ files:
|
|
187
189
|
- lib/rubocop/cop/rails/time_zone.rb
|
188
190
|
- lib/rubocop/cop/rails/time_zone_assignment.rb
|
189
191
|
- lib/rubocop/cop/rails/to_formatted_s.rb
|
192
|
+
- lib/rubocop/cop/rails/to_s_with_argument.rb
|
193
|
+
- lib/rubocop/cop/rails/top_level_hash_with_indifferent_access.rb
|
190
194
|
- lib/rubocop/cop/rails/transaction_exit_statement.rb
|
191
195
|
- lib/rubocop/cop/rails/uniq_before_pluck.rb
|
192
196
|
- lib/rubocop/cop/rails/unique_validation_without_index.rb
|
@@ -195,6 +199,7 @@ files:
|
|
195
199
|
- lib/rubocop/cop/rails/validation.rb
|
196
200
|
- lib/rubocop/cop/rails/where_equals.rb
|
197
201
|
- lib/rubocop/cop/rails/where_exists.rb
|
202
|
+
- lib/rubocop/cop/rails/where_missing.rb
|
198
203
|
- lib/rubocop/cop/rails/where_not.rb
|
199
204
|
- lib/rubocop/cop/rails_cops.rb
|
200
205
|
- lib/rubocop/rails.rb
|
@@ -209,7 +214,7 @@ metadata:
|
|
209
214
|
homepage_uri: https://docs.rubocop.org/rubocop-rails/
|
210
215
|
changelog_uri: https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md
|
211
216
|
source_code_uri: https://github.com/rubocop/rubocop-rails/
|
212
|
-
documentation_uri: https://docs.rubocop.org/rubocop-rails/2.
|
217
|
+
documentation_uri: https://docs.rubocop.org/rubocop-rails/2.16/
|
213
218
|
bug_tracker_uri: https://github.com/rubocop/rubocop-rails/issues
|
214
219
|
rubygems_mfa_required: 'true'
|
215
220
|
post_install_message:
|
@@ -227,7 +232,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
227
232
|
- !ruby/object:Gem::Version
|
228
233
|
version: '0'
|
229
234
|
requirements: []
|
230
|
-
rubygems_version: 3.
|
235
|
+
rubygems_version: 3.2.22
|
231
236
|
signing_key:
|
232
237
|
specification_version: 4
|
233
238
|
summary: Automatic Rails code style checking tool.
|
data/bin/console
DELETED