rubocop-rails 2.25.0 → 2.29.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +52 -2
  4. data/config/default.yml +47 -9
  5. data/lib/rubocop/cop/mixin/index_method.rb +12 -5
  6. data/lib/rubocop/cop/mixin/routes_helper.rb +20 -0
  7. data/lib/rubocop/cop/mixin/target_rails_version.rb +3 -5
  8. data/lib/rubocop/cop/rails/action_order.rb +1 -5
  9. data/lib/rubocop/cop/rails/active_record_callbacks_order.rb +1 -5
  10. data/lib/rubocop/cop/rails/add_column_index.rb +1 -0
  11. data/lib/rubocop/cop/rails/application_record.rb +4 -0
  12. data/lib/rubocop/cop/rails/bulk_change_table.rb +11 -4
  13. data/lib/rubocop/cop/rails/compact_blank.rb +29 -8
  14. data/lib/rubocop/cop/rails/dangerous_column_names.rb +2 -0
  15. data/lib/rubocop/cop/rails/date.rb +2 -2
  16. data/lib/rubocop/cop/rails/enum_hash.rb +31 -8
  17. data/lib/rubocop/cop/rails/enum_syntax.rb +130 -0
  18. data/lib/rubocop/cop/rails/enum_uniqueness.rb +29 -7
  19. data/lib/rubocop/cop/rails/env_local.rb +26 -3
  20. data/lib/rubocop/cop/rails/file_path.rb +4 -1
  21. data/lib/rubocop/cop/rails/http_positional_arguments.rb +7 -0
  22. data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +1 -1
  23. data/lib/rubocop/cop/rails/index_by.rb +28 -12
  24. data/lib/rubocop/cop/rails/index_with.rb +28 -12
  25. data/lib/rubocop/cop/rails/link_to_blank.rb +2 -2
  26. data/lib/rubocop/cop/rails/match_route.rb +1 -9
  27. data/lib/rubocop/cop/rails/multiple_route_paths.rb +50 -0
  28. data/lib/rubocop/cop/rails/not_null_column.rb +8 -2
  29. data/lib/rubocop/cop/rails/pluck.rb +20 -0
  30. data/lib/rubocop/cop/rails/pluck_in_where.rb +17 -8
  31. data/lib/rubocop/cop/rails/pluralization_grammar.rb +29 -15
  32. data/lib/rubocop/cop/rails/present.rb +0 -2
  33. data/lib/rubocop/cop/rails/redundant_active_record_all_method.rb +1 -30
  34. data/lib/rubocop/cop/rails/redundant_foreign_key.rb +1 -1
  35. data/lib/rubocop/cop/rails/redundant_presence_validation_on_belongs_to.rb +9 -0
  36. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +1 -1
  37. data/lib/rubocop/cop/rails/reflection_class_name.rb +1 -1
  38. data/lib/rubocop/cop/rails/render_plain_text.rb +6 -3
  39. data/lib/rubocop/cop/rails/request_referer.rb +1 -1
  40. data/lib/rubocop/cop/rails/reversible_migration.rb +3 -1
  41. data/lib/rubocop/cop/rails/root_pathname_methods.rb +15 -11
  42. data/lib/rubocop/cop/rails/save_bang.rb +1 -1
  43. data/lib/rubocop/cop/rails/schema_comment.rb +1 -0
  44. data/lib/rubocop/cop/rails/select_map.rb +3 -2
  45. data/lib/rubocop/cop/rails/skips_model_validations.rb +7 -2
  46. data/lib/rubocop/cop/rails/squished_sql_heredocs.rb +1 -1
  47. data/lib/rubocop/cop/rails/strong_parameters_expect.rb +104 -0
  48. data/lib/rubocop/cop/rails/three_state_boolean_column.rb +2 -1
  49. data/lib/rubocop/cop/rails/time_zone.rb +13 -6
  50. data/lib/rubocop/cop/rails/transaction_exit_statement.rb +5 -0
  51. data/lib/rubocop/cop/rails/validation.rb +4 -1
  52. data/lib/rubocop/cop/rails/where_equals.rb +28 -12
  53. data/lib/rubocop/cop/rails/where_not.rb +11 -6
  54. data/lib/rubocop/cop/rails/where_range.rb +89 -43
  55. data/lib/rubocop/cop/rails_cops.rb +4 -0
  56. data/lib/rubocop/rails/migration_file_skippable.rb +54 -0
  57. data/lib/rubocop/rails/schema_loader/schema.rb +1 -1
  58. data/lib/rubocop/rails/version.rb +1 -1
  59. data/lib/rubocop/rails.rb +0 -1
  60. data/lib/rubocop-rails.rb +3 -0
  61. metadata +11 -9
@@ -4,7 +4,8 @@ module RuboCop
4
4
  module Cop
5
5
  module Rails
6
6
  # Identifies places where manually constructed SQL
7
- # in `where` can be replaced with `where(attribute: value)`.
7
+ # in `where` and `where.not` can be replaced with
8
+ # `where(attribute: value)` and `where.not(attribute: value)`.
8
9
  #
9
10
  # @safety
10
11
  # This cop's autocorrection is unsafe because is may change SQL.
@@ -13,6 +14,7 @@ module RuboCop
13
14
  # @example
14
15
  # # bad
15
16
  # User.where('name = ?', 'Gabe')
17
+ # User.where.not('name = ?', 'Gabe')
16
18
  # User.where('name = :name', name: 'Gabe')
17
19
  # User.where('name IS NULL')
18
20
  # User.where('name IN (?)', ['john', 'jane'])
@@ -21,6 +23,7 @@ module RuboCop
21
23
  #
22
24
  # # good
23
25
  # User.where(name: 'Gabe')
26
+ # User.where.not(name: 'Gabe')
24
27
  # User.where(name: nil)
25
28
  # User.where(name: ['john', 'jane'])
26
29
  # User.where(users: { name: 'Gabe' })
@@ -29,25 +32,27 @@ module RuboCop
29
32
  extend AutoCorrector
30
33
 
31
34
  MSG = 'Use `%<good_method>s` instead of manually constructing SQL.'
32
- RESTRICT_ON_SEND = %i[where].freeze
35
+ RESTRICT_ON_SEND = %i[where not].freeze
33
36
 
34
37
  def_node_matcher :where_method_call?, <<~PATTERN
35
38
  {
36
- (call _ :where (array $str_type? $_ ?))
37
- (call _ :where $str_type? $_ ?)
39
+ (call _ {:where :not} (array $str_type? $_ ?))
40
+ (call _ {:where :not} $str_type? $_ ?)
38
41
  }
39
42
  PATTERN
40
43
 
41
44
  def on_send(node)
45
+ return if node.method?(:not) && !where_not?(node)
46
+
42
47
  where_method_call?(node) do |template_node, value_node|
43
48
  value_node = value_node.first
44
49
 
45
50
  range = offense_range(node)
46
51
 
47
- column_and_value = extract_column_and_value(template_node, value_node)
48
- return unless column_and_value
52
+ column, value = extract_column_and_value(template_node, value_node)
53
+ return unless value
49
54
 
50
- good_method = build_good_method(*column_and_value)
55
+ good_method = build_good_method(node.method_name, column, value)
51
56
  message = format(MSG, good_method: good_method)
52
57
 
53
58
  add_offense(range, message: message) do |corrector|
@@ -69,11 +74,12 @@ module RuboCop
69
74
  range_between(node.loc.selector.begin_pos, node.source_range.end_pos)
70
75
  end
71
76
 
77
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
72
78
  def extract_column_and_value(template_node, value_node)
73
79
  value =
74
80
  case template_node.value
75
81
  when EQ_ANONYMOUS_RE, IN_ANONYMOUS_RE
76
- value_node.source
82
+ value_node&.source
77
83
  when EQ_NAMED_RE, IN_NAMED_RE
78
84
  return unless value_node&.hash_type?
79
85
 
@@ -85,18 +91,28 @@ module RuboCop
85
91
  return
86
92
  end
87
93
 
88
- [Regexp.last_match(1), value]
94
+ column_qualifier = Regexp.last_match(1)
95
+ return if column_qualifier.count('.') > 1
96
+
97
+ [column_qualifier, value]
89
98
  end
99
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
90
100
 
91
- def build_good_method(column, value)
101
+ def build_good_method(method_name, column, value)
92
102
  if column.include?('.')
93
103
  table, column = column.split('.')
94
104
 
95
- "where(#{table}: { #{column}: #{value} })"
105
+ "#{method_name}(#{table}: { #{column}: #{value} })"
96
106
  else
97
- "where(#{column}: #{value})"
107
+ "#{method_name}(#{column}: #{value})"
98
108
  end
99
109
  end
110
+
111
+ def where_not?(node)
112
+ return false unless (receiver = node.receiver)
113
+
114
+ receiver.send_type? && receiver.method?(:where)
115
+ end
100
116
  end
101
117
  end
102
118
  end
@@ -43,10 +43,10 @@ module RuboCop
43
43
 
44
44
  range = offense_range(node)
45
45
 
46
- column_and_value = extract_column_and_value(template_node, value_node)
47
- return unless column_and_value
46
+ column, value = extract_column_and_value(template_node, value_node)
47
+ return unless value
48
48
 
49
- good_method = build_good_method(node.loc.dot&.source, *column_and_value)
49
+ good_method = build_good_method(node.loc.dot&.source, column, value)
50
50
  message = format(MSG, good_method: good_method)
51
51
 
52
52
  add_offense(range, message: message) do |corrector|
@@ -68,13 +68,14 @@ module RuboCop
68
68
  range_between(node.loc.selector.begin_pos, node.source_range.end_pos)
69
69
  end
70
70
 
71
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
71
72
  def extract_column_and_value(template_node, value_node)
72
73
  value =
73
74
  case template_node.value
74
75
  when NOT_EQ_ANONYMOUS_RE, NOT_IN_ANONYMOUS_RE
75
- value_node.source
76
+ value_node&.source
76
77
  when NOT_EQ_NAMED_RE, NOT_IN_NAMED_RE
77
- return unless value_node.hash_type?
78
+ return unless value_node&.hash_type?
78
79
 
79
80
  pair = value_node.pairs.find { |p| p.key.value.to_sym == Regexp.last_match(2).to_sym }
80
81
  pair.value.source
@@ -84,8 +85,12 @@ module RuboCop
84
85
  return
85
86
  end
86
87
 
87
- [Regexp.last_match(1), value]
88
+ column_qualifier = Regexp.last_match(1)
89
+ return if column_qualifier.count('.') > 1
90
+
91
+ [column_qualifier, value]
88
92
  end
93
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
89
94
 
90
95
  def build_good_method(dot, column, value)
91
96
  dot ||= '.'
@@ -6,6 +6,14 @@ module RuboCop
6
6
  # Identifies places where manually constructed SQL
7
7
  # in `where` can be replaced with ranges.
8
8
  #
9
+ # @safety
10
+ # This cop's autocorrection is unsafe because it can change the query
11
+ # by explicitly attaching the column to the wrong table.
12
+ # For example, `Booking.joins(:events).where('end_at < ?', Time.current)` will correctly
13
+ # implicitly attach the `end_at` column to the `events` table. But when autocorrected to
14
+ # `Booking.joins(:events).where(end_at: ...Time.current)`, it will now be incorrectly
15
+ # explicitly attached to the `bookings` table.
16
+ #
9
17
  # @example
10
18
  # # bad
11
19
  # User.where('age >= ?', 18)
@@ -37,17 +45,17 @@ module RuboCop
37
45
  RESTRICT_ON_SEND = %i[where not].freeze
38
46
 
39
47
  # column >= ?
40
- GTEQ_ANONYMOUS_RE = /\A([\w.]+)\s+>=\s+\?\z/.freeze
48
+ GTEQ_ANONYMOUS_RE = /\A\s*([\w.]+)\s+>=\s+\?\s*\z/.freeze
41
49
  # column <[=] ?
42
- LTEQ_ANONYMOUS_RE = /\A([\w.]+)\s+(<=?)\s+\?\z/.freeze
50
+ LTEQ_ANONYMOUS_RE = /\A\s*([\w.]+)\s+(<=?)\s+\?\s*\z/.freeze
43
51
  # column >= ? AND column <[=] ?
44
- RANGE_ANONYMOUS_RE = /\A([\w.]+)\s+>=\s+\?\s+AND\s+\1\s+(<=?)\s+\?\z/i.freeze
52
+ RANGE_ANONYMOUS_RE = /\A\s*([\w.]+)\s+>=\s+\?\s+AND\s+\1\s+(<=?)\s+\?\s*\z/i.freeze
45
53
  # column >= :value
46
- GTEQ_NAMED_RE = /\A([\w.]+)\s+>=\s+:(\w+)\z/.freeze
54
+ GTEQ_NAMED_RE = /\A\s*([\w.]+)\s+>=\s+:(\w+)\s*\z/.freeze
47
55
  # column <[=] :value
48
- LTEQ_NAMED_RE = /\A([\w.]+)\s+(<=?)\s+:(\w+)\z/.freeze
56
+ LTEQ_NAMED_RE = /\A\s*([\w.]+)\s+(<=?)\s+:(\w+)\s*\z/.freeze
49
57
  # column >= :value1 AND column <[=] :value2
50
- RANGE_NAMED_RE = /\A([\w.]+)\s+>=\s+:(\w+)\s+AND\s+\1\s+(<=?)\s+:(\w+)\z/i.freeze
58
+ RANGE_NAMED_RE = /\A\s*([\w.]+)\s+>=\s+:(\w+)\s+AND\s+\1\s+(<=?)\s+:(\w+)\s*\z/i.freeze
51
59
 
52
60
  minimum_target_ruby_version 2.6
53
61
  minimum_target_rails_version 6.0
@@ -81,52 +89,73 @@ module RuboCop
81
89
 
82
90
  def where_not?(node)
83
91
  receiver = node.receiver
84
- receiver&.send_type? && receiver&.method?(:where)
92
+ receiver&.send_type? && receiver.method?(:where)
85
93
  end
86
94
 
87
95
  # rubocop:disable Metrics
88
96
  def extract_column_and_value(template_node, values_node)
89
- value =
90
- case template_node.value
91
- when GTEQ_ANONYMOUS_RE
92
- "#{values_node[0].source}.."
93
- when LTEQ_ANONYMOUS_RE
94
- range_operator = range_operator(Regexp.last_match(2))
95
- "#{range_operator}#{values_node[0].source}" if target_ruby_version >= 2.7
96
- when RANGE_ANONYMOUS_RE
97
- if values_node.size >= 2
98
- range_operator = range_operator(Regexp.last_match(2))
99
- "#{values_node[0].source}#{range_operator}#{values_node[1].source}"
100
- end
101
- when GTEQ_NAMED_RE
102
- value_node = values_node[0]
97
+ case template_node.value
98
+ when GTEQ_ANONYMOUS_RE
99
+ lhs = values_node[0]
100
+ operator = '..'
101
+ when LTEQ_ANONYMOUS_RE
102
+ if target_ruby_version >= 2.7
103
+ operator = range_operator(Regexp.last_match(2))
104
+ rhs = values_node[0]
105
+ end
106
+ when RANGE_ANONYMOUS_RE
107
+ if values_node.size >= 2
108
+ lhs = values_node[0]
109
+ operator = range_operator(Regexp.last_match(2))
110
+ rhs = values_node[1]
111
+ end
112
+ when GTEQ_NAMED_RE
113
+ value_node = values_node[0]
103
114
 
104
- if value_node.hash_type?
105
- pair = find_pair(value_node, Regexp.last_match(2))
106
- "#{pair.value.source}.." if pair
107
- end
108
- when LTEQ_NAMED_RE
109
- value_node = values_node[0]
110
-
111
- if value_node.hash_type?
112
- pair = find_pair(value_node, Regexp.last_match(2))
113
- if pair && target_ruby_version >= 2.7
114
- range_operator = range_operator(Regexp.last_match(2))
115
- "#{range_operator}#{pair.value.source}"
116
- end
115
+ if value_node.hash_type?
116
+ pair = find_pair(value_node, Regexp.last_match(2))
117
+ lhs = pair.value
118
+ operator = '..'
119
+ end
120
+ when LTEQ_NAMED_RE
121
+ value_node = values_node[0]
122
+
123
+ if value_node.hash_type?
124
+ pair = find_pair(value_node, Regexp.last_match(2))
125
+ if pair && target_ruby_version >= 2.7
126
+ operator = range_operator(Regexp.last_match(2))
127
+ rhs = pair.value
117
128
  end
118
- when RANGE_NAMED_RE
119
- value_node = values_node[0]
120
-
121
- if value_node.hash_type?
122
- range_operator = range_operator(Regexp.last_match(3))
123
- pair1 = find_pair(value_node, Regexp.last_match(2))
124
- pair2 = find_pair(value_node, Regexp.last_match(4))
125
- "#{pair1.value.source}#{range_operator}#{pair2.value.source}" if pair1 && pair2
129
+ end
130
+ when RANGE_NAMED_RE
131
+ value_node = values_node[0]
132
+
133
+ if value_node.hash_type?
134
+ pair1 = find_pair(value_node, Regexp.last_match(2))
135
+ pair2 = find_pair(value_node, Regexp.last_match(4))
136
+
137
+ if pair1 && pair2
138
+ lhs = pair1.value
139
+ operator = range_operator(Regexp.last_match(3))
140
+ rhs = pair2.value
126
141
  end
127
142
  end
143
+ else
144
+ return
145
+ end
128
146
 
129
- [Regexp.last_match(1), value] if value
147
+ if lhs
148
+ lhs_source = parentheses_needed?(lhs) ? "(#{lhs.source})" : lhs.source
149
+ end
150
+
151
+ if rhs
152
+ rhs_source = parentheses_needed?(rhs) ? "(#{rhs.source})" : rhs.source
153
+ end
154
+
155
+ column_qualifier = Regexp.last_match(1)
156
+ return if column_qualifier.count('.') > 1
157
+
158
+ [column_qualifier, "#{lhs_source}#{operator}#{rhs_source}"] if operator
130
159
  end
131
160
  # rubocop:enable Metrics
132
161
 
@@ -151,6 +180,23 @@ module RuboCop
151
180
  "#{method_name}(#{column}: #{value})"
152
181
  end
153
182
  end
183
+
184
+ def parentheses_needed?(node)
185
+ !parentheses_not_needed?(node)
186
+ end
187
+
188
+ def parentheses_not_needed?(node)
189
+ node.variable? ||
190
+ node.literal? ||
191
+ node.reference? ||
192
+ node.const_type? ||
193
+ node.begin_type? ||
194
+ parenthesized_call_node?(node)
195
+ end
196
+
197
+ def parenthesized_call_node?(node)
198
+ node.call_type? && (node.arguments.empty? || node.parenthesized_call?)
199
+ end
154
200
  end
155
201
  end
156
202
  end
@@ -7,9 +7,11 @@ require_relative 'mixin/database_type_resolvable'
7
7
  require_relative 'mixin/enforce_superclass'
8
8
  require_relative 'mixin/index_method'
9
9
  require_relative 'mixin/migrations_helper'
10
+ require_relative 'mixin/routes_helper'
10
11
  require_relative 'mixin/target_rails_version'
11
12
 
12
13
  require_relative 'rails/action_controller_flash_before_render'
14
+ require_relative 'rails/strong_parameters_expect'
13
15
  require_relative 'rails/action_controller_test_case'
14
16
  require_relative 'rails/action_filter'
15
17
  require_relative 'rails/action_order'
@@ -46,6 +48,7 @@ require_relative 'rails/duration_arithmetic'
46
48
  require_relative 'rails/dynamic_find_by'
47
49
  require_relative 'rails/eager_evaluation_log_message'
48
50
  require_relative 'rails/enum_hash'
51
+ require_relative 'rails/enum_syntax'
49
52
  require_relative 'rails/enum_uniqueness'
50
53
  require_relative 'rails/env_local'
51
54
  require_relative 'rails/environment_comparison'
@@ -76,6 +79,7 @@ require_relative 'rails/link_to_blank'
76
79
  require_relative 'rails/mailer_name'
77
80
  require_relative 'rails/match_route'
78
81
  require_relative 'rails/migration_class_name'
82
+ require_relative 'rails/multiple_route_paths'
79
83
  require_relative 'rails/negate_include'
80
84
  require_relative 'rails/not_null_column'
81
85
  require_relative 'rails/order_by_id'
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Rails
5
+ # This module allows cops to detect and ignore files that have already been migrated
6
+ # by leveraging the `AllCops: MigratedSchemaVersion` configuration.
7
+ #
8
+ # [source,yaml]
9
+ # -----
10
+ # AllCops:
11
+ # MigratedSchemaVersion: '20241225000000'
12
+ # -----
13
+ #
14
+ # When applied to cops, it overrides the `add_global_offense` and `add_offense` methods,
15
+ # ensuring that cops skip processing if the file is determined to be a migrated file
16
+ # based on the schema version.
17
+ #
18
+ # @api private
19
+ module MigrationFileSkippable
20
+ def add_global_offense(message = nil, severity: nil)
21
+ return if already_migrated_file?
22
+
23
+ super if method(__method__).super_method
24
+ end
25
+
26
+ def add_offense(node_or_range, message: nil, severity: nil, &block)
27
+ return if already_migrated_file?
28
+
29
+ super if method(__method__).super_method
30
+ end
31
+
32
+ def self.apply_to_cops!
33
+ RuboCop::Cop::Registry.all.each { |cop| cop.prepend(MigrationFileSkippable) }
34
+ end
35
+
36
+ private
37
+
38
+ def already_migrated_file?
39
+ return false unless migrated_schema_version
40
+
41
+ match_data = File.basename(processed_source.file_path).match(/(?<timestamp>\d{14})/)
42
+ schema_version = match_data['timestamp'] if match_data
43
+
44
+ return false unless schema_version
45
+
46
+ schema_version <= migrated_schema_version.to_s # Ignore applied migration files.
47
+ end
48
+
49
+ def migrated_schema_version
50
+ @migrated_schema_version ||= config.for_all_cops.fetch('MigratedSchemaVersion', nil)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -178,7 +178,7 @@ module RuboCop
178
178
  attr_reader :table_name
179
179
 
180
180
  def initialize(node)
181
- super(node)
181
+ super
182
182
 
183
183
  @table_name = node.first_argument.value
184
184
  @columns, @expression = build_columns_or_expr(node.arguments[1])
@@ -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.25.0'
7
+ STRING = '2.29.0'
8
8
 
9
9
  def self.document_version
10
10
  STRING.match('\d+\.\d+').to_s
data/lib/rubocop/rails.rb CHANGED
@@ -5,7 +5,6 @@ module RuboCop
5
5
  module Rails
6
6
  PROJECT_ROOT = Pathname.new(__dir__).parent.parent.expand_path.freeze
7
7
  CONFIG_DEFAULT = PROJECT_ROOT.join('config', 'default.yml').freeze
8
- CONFIG = YAML.safe_load(CONFIG_DEFAULT.read, permitted_classes: [Regexp, Symbol]).freeze
9
8
 
10
9
  private_constant(:CONFIG_DEFAULT, :PROJECT_ROOT)
11
10
 
data/lib/rubocop-rails.rb CHANGED
@@ -15,6 +15,9 @@ RuboCop::Rails::Inject.defaults!
15
15
 
16
16
  require_relative 'rubocop/cop/rails_cops'
17
17
 
18
+ require_relative 'rubocop/rails/migration_file_skippable'
19
+ RuboCop::Rails::MigrationFileSkippable.apply_to_cops!
20
+
18
21
  RuboCop::Cop::Style::HashExcept.minimum_target_ruby_version(2.0)
19
22
 
20
23
  RuboCop::Cop::Style::InverseMethods.singleton_class.prepend(
metadata CHANGED
@@ -1,16 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.25.0
4
+ version: 2.29.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
8
8
  - Jonas Arvidsson
9
9
  - Yuji Nakayama
10
- autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2024-05-17 00:00:00.000000000 Z
12
+ date: 2025-01-18 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: activesupport
@@ -46,7 +45,7 @@ dependencies:
46
45
  requirements:
47
46
  - - ">="
48
47
  - !ruby/object:Gem::Version
49
- version: 1.33.0
48
+ version: 1.52.0
50
49
  - - "<"
51
50
  - !ruby/object:Gem::Version
52
51
  version: '2.0'
@@ -56,7 +55,7 @@ dependencies:
56
55
  requirements:
57
56
  - - ">="
58
57
  - !ruby/object:Gem::Version
59
- version: 1.33.0
58
+ version: 1.52.0
60
59
  - - "<"
61
60
  - !ruby/object:Gem::Version
62
61
  version: '2.0'
@@ -102,6 +101,7 @@ files:
102
101
  - lib/rubocop/cop/mixin/enforce_superclass.rb
103
102
  - lib/rubocop/cop/mixin/index_method.rb
104
103
  - lib/rubocop/cop/mixin/migrations_helper.rb
104
+ - lib/rubocop/cop/mixin/routes_helper.rb
105
105
  - lib/rubocop/cop/mixin/target_rails_version.rb
106
106
  - lib/rubocop/cop/rails/action_controller_flash_before_render.rb
107
107
  - lib/rubocop/cop/rails/action_controller_test_case.rb
@@ -140,6 +140,7 @@ files:
140
140
  - lib/rubocop/cop/rails/dynamic_find_by.rb
141
141
  - lib/rubocop/cop/rails/eager_evaluation_log_message.rb
142
142
  - lib/rubocop/cop/rails/enum_hash.rb
143
+ - lib/rubocop/cop/rails/enum_syntax.rb
143
144
  - lib/rubocop/cop/rails/enum_uniqueness.rb
144
145
  - lib/rubocop/cop/rails/env_local.rb
145
146
  - lib/rubocop/cop/rails/environment_comparison.rb
@@ -170,6 +171,7 @@ files:
170
171
  - lib/rubocop/cop/rails/mailer_name.rb
171
172
  - lib/rubocop/cop/rails/match_route.rb
172
173
  - lib/rubocop/cop/rails/migration_class_name.rb
174
+ - lib/rubocop/cop/rails/multiple_route_paths.rb
173
175
  - lib/rubocop/cop/rails/negate_include.rb
174
176
  - lib/rubocop/cop/rails/not_null_column.rb
175
177
  - lib/rubocop/cop/rails/order_by_id.rb
@@ -213,6 +215,7 @@ files:
213
215
  - lib/rubocop/cop/rails/skips_model_validations.rb
214
216
  - lib/rubocop/cop/rails/squished_sql_heredocs.rb
215
217
  - lib/rubocop/cop/rails/strip_heredoc.rb
218
+ - lib/rubocop/cop/rails/strong_parameters_expect.rb
216
219
  - lib/rubocop/cop/rails/table_name_assignment.rb
217
220
  - lib/rubocop/cop/rails/three_state_boolean_column.rb
218
221
  - lib/rubocop/cop/rails/time_zone.rb
@@ -236,6 +239,7 @@ files:
236
239
  - lib/rubocop/cop/rails_cops.rb
237
240
  - lib/rubocop/rails.rb
238
241
  - lib/rubocop/rails/inject.rb
242
+ - lib/rubocop/rails/migration_file_skippable.rb
239
243
  - lib/rubocop/rails/schema_loader.rb
240
244
  - lib/rubocop/rails/schema_loader/schema.rb
241
245
  - lib/rubocop/rails/version.rb
@@ -246,10 +250,9 @@ metadata:
246
250
  homepage_uri: https://docs.rubocop.org/rubocop-rails/
247
251
  changelog_uri: https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md
248
252
  source_code_uri: https://github.com/rubocop/rubocop-rails/
249
- documentation_uri: https://docs.rubocop.org/rubocop-rails/2.25/
253
+ documentation_uri: https://docs.rubocop.org/rubocop-rails/2.29/
250
254
  bug_tracker_uri: https://github.com/rubocop/rubocop-rails/issues
251
255
  rubygems_mfa_required: 'true'
252
- post_install_message:
253
256
  rdoc_options: []
254
257
  require_paths:
255
258
  - lib
@@ -264,8 +267,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
264
267
  - !ruby/object:Gem::Version
265
268
  version: '0'
266
269
  requirements: []
267
- rubygems_version: 3.5.3
268
- signing_key:
270
+ rubygems_version: 3.6.2
269
271
  specification_version: 4
270
272
  summary: Automatic Rails code style checking tool.
271
273
  test_files: []