rubocop-rails 2.19.1 → 2.21.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -1
  3. data/config/default.yml +86 -12
  4. data/lib/rubocop/cop/mixin/index_method.rb +2 -2
  5. data/lib/rubocop/cop/rails/action_controller_flash_before_render.rb +1 -1
  6. data/lib/rubocop/cop/rails/action_controller_test_case.rb +2 -2
  7. data/lib/rubocop/cop/rails/assert_not.rb +0 -1
  8. data/lib/rubocop/cop/rails/bulk_change_table.rb +20 -3
  9. data/lib/rubocop/cop/rails/dangerous_column_names.rb +439 -0
  10. data/lib/rubocop/cop/rails/date.rb +12 -3
  11. data/lib/rubocop/cop/rails/duplicate_association.rb +3 -0
  12. data/lib/rubocop/cop/rails/dynamic_find_by.rb +3 -3
  13. data/lib/rubocop/cop/rails/file_path.rb +129 -13
  14. data/lib/rubocop/cop/rails/find_each.rb +1 -1
  15. data/lib/rubocop/cop/rails/freeze_time.rb +1 -1
  16. data/lib/rubocop/cop/rails/http_status.rb +4 -3
  17. data/lib/rubocop/cop/rails/i18n_lazy_lookup.rb +63 -13
  18. data/lib/rubocop/cop/rails/i18n_locale_texts.rb +5 -1
  19. data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +22 -2
  20. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +9 -10
  21. data/lib/rubocop/cop/rails/not_null_column.rb +1 -1
  22. data/lib/rubocop/cop/rails/rake_environment.rb +20 -4
  23. data/lib/rubocop/cop/rails/redundant_active_record_all_method.rb +168 -0
  24. data/lib/rubocop/cop/rails/refute_methods.rb +0 -1
  25. data/lib/rubocop/cop/rails/reversible_migration.rb +1 -1
  26. data/lib/rubocop/cop/rails/root_pathname_methods.rb +38 -4
  27. data/lib/rubocop/cop/rails/save_bang.rb +2 -2
  28. data/lib/rubocop/cop/rails/schema_comment.rb +16 -10
  29. data/lib/rubocop/cop/rails/select_map.rb +78 -0
  30. data/lib/rubocop/cop/rails/squished_sql_heredocs.rb +0 -1
  31. data/lib/rubocop/cop/rails/three_state_boolean_column.rb +2 -4
  32. data/lib/rubocop/cop/rails/time_zone.rb +12 -5
  33. data/lib/rubocop/cop/rails/transaction_exit_statement.rb +35 -9
  34. data/lib/rubocop/cop/rails/unique_validation_without_index.rb +15 -19
  35. data/lib/rubocop/cop/rails/unused_render_content.rb +67 -0
  36. data/lib/rubocop/cop/rails/where_exists.rb +0 -1
  37. data/lib/rubocop/cop/rails_cops.rb +4 -0
  38. data/lib/rubocop/rails/schema_loader/schema.rb +4 -4
  39. data/lib/rubocop/rails/schema_loader.rb +1 -1
  40. data/lib/rubocop/rails/version.rb +1 -1
  41. data/lib/rubocop-rails.rb +8 -0
  42. metadata +8 -4
@@ -0,0 +1,439 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Rails
6
+ # Avoid dangerous column names.
7
+ #
8
+ # Some column names are considered dangerous because they would overwrite methods already defined.
9
+ #
10
+ # @example
11
+ # # bad
12
+ # add_column :users, :save
13
+ #
14
+ # # good
15
+ # add_column :users, :saved
16
+ class DangerousColumnNames < Base # rubocop:disable Metrics/ClassLength
17
+ COLUMN_TYPE_METHOD_NAMES = %i[
18
+ bigint
19
+ binary
20
+ blob
21
+ boolean
22
+ date
23
+ datetime
24
+ decimal
25
+ float
26
+ integer
27
+ numeric
28
+ primary_key
29
+ string
30
+ text
31
+ time
32
+ ].to_set.freeze
33
+
34
+ # Generated from `ActiveRecord::AttributeMethods.dangerous_attribute_methods` on activerecord 7.0.5.
35
+ # rubocop:disable Metrics/CollectionLiteralLength
36
+ DANGEROUS_COLUMN_NAMES = %w[
37
+ __callbacks
38
+ _assign_attribute
39
+ _assign_attributes
40
+ _before_commit_callbacks
41
+ _commit_callbacks
42
+ _committed_already_called
43
+ _create_callbacks
44
+ _create_record
45
+ _delete_row
46
+ _destroy
47
+ _destroy_callbacks
48
+ _ensure_no_duplicate_errors
49
+ _find_callbacks
50
+ _find_record
51
+ _has_attribute
52
+ _initialize_callbacks
53
+ _lock_value_for_database
54
+ _merge_attributes
55
+ _primary_key_constraints_hash
56
+ _raise_readonly_record_error
57
+ _raise_record_not_destroyed
58
+ _raise_record_not_touched_error
59
+ _read_attribute
60
+ _record_changed
61
+ _reflections
62
+ _rollback_callbacks
63
+ _run_before_commit_callbacks
64
+ _run_commit_callbacks
65
+ _run_create_callbacks
66
+ _run_destroy_callbacks
67
+ _run_find_callbacks
68
+ _run_initialize_callbacks
69
+ _run_rollback_callbacks
70
+ _run_save_callbacks
71
+ _run_touch_callbacks
72
+ _run_update_callbacks
73
+ _run_validate_callbacks
74
+ _run_validation_callbacks
75
+ _save_callbacks
76
+ _touch_callbacks
77
+ _touch_row
78
+ _trigger_destroy_callback
79
+ _trigger_update_callback
80
+ _update_callbacks
81
+ _update_record
82
+ _update_row
83
+ _validate_callbacks
84
+ _validation_callbacks
85
+ _validators
86
+ _write_attribute
87
+ []
88
+ []=
89
+ accessed_fields
90
+ add_to_transaction
91
+ aggregate_reflections
92
+ all_timestamp_attributes_in_model
93
+ allow_destroy
94
+ apply_scoping
95
+ around_save_collection_association
96
+ assign_attributes
97
+ assign_multiparameter_attributes
98
+ assign_nested_attributes_for_collection_association
99
+ assign_nested_attributes_for_one_to_one_association
100
+ assign_nested_parameter_attributes
101
+ assign_to_or_mark_for_destruction
102
+ associated_records_to_validate_or_save
103
+ association
104
+ association_cached
105
+ association_foreign_key_changed
106
+ association_instance_get
107
+ association_instance_set
108
+ association_valid
109
+ attachment_changes
110
+ attachment_reflections
111
+ attribute
112
+ attribute_aliases
113
+ attribute_before_last_save
114
+ attribute_before_type_cast
115
+ attribute_came_from_user
116
+ attribute_change
117
+ attribute_change_to_be_saved
118
+ attribute_changed
119
+ attribute_changed_in_place
120
+ attribute_for_database
121
+ attribute_for_inspect
122
+ attribute_in_database
123
+ attribute_method
124
+ attribute_method_matchers
125
+ attribute_missing
126
+ attribute_names
127
+ attribute_names_for_partial_inserts
128
+ attribute_names_for_partial_updates
129
+ attribute_names_for_serialization
130
+ attribute_present
131
+ attribute_previous_change
132
+ attribute_previously_changed
133
+ attribute_previously_was
134
+ attribute_was
135
+ attribute_will_change
136
+ attribute=
137
+ attributes
138
+ attributes_before_type_cast
139
+ attributes_for_create
140
+ attributes_for_database
141
+ attributes_for_update
142
+ attributes_in_database
143
+ attributes_with_values
144
+ attributes=
145
+ automatic_scope_inversing
146
+ becomes
147
+ before_committed
148
+ belongs_to_touch_method
149
+ broadcast_action
150
+ broadcast_action_later
151
+ broadcast_action_later_to
152
+ broadcast_action_to
153
+ broadcast_after_to
154
+ broadcast_append
155
+ broadcast_append_later
156
+ broadcast_append_later_to
157
+ broadcast_append_to
158
+ broadcast_before_to
159
+ broadcast_prepend
160
+ broadcast_prepend_later
161
+ broadcast_prepend_later_to
162
+ broadcast_prepend_to
163
+ broadcast_remove
164
+ broadcast_remove_to
165
+ broadcast_render
166
+ broadcast_render_later
167
+ broadcast_render_later_to
168
+ broadcast_render_to
169
+ broadcast_rendering_with_defaults
170
+ broadcast_replace
171
+ broadcast_replace_later
172
+ broadcast_replace_later_to
173
+ broadcast_replace_to
174
+ broadcast_target_default
175
+ broadcast_update
176
+ broadcast_update_later
177
+ broadcast_update_later_to
178
+ broadcast_update_to
179
+ build_decrypt_attribute_assignments
180
+ build_encrypt_attribute_assignments
181
+ cache_key
182
+ cache_key_with_version
183
+ cache_timestamp_format
184
+ cache_version
185
+ cache_versioning
186
+ call_reject_if
187
+ can_use_fast_cache_version
188
+ cant_modify_encrypted_attributes_when_frozen
189
+ changed
190
+ changed_attribute_names_to_save
191
+ changed_attributes
192
+ changed_for_autosave
193
+ changes
194
+ changes_applied
195
+ changes_to_save
196
+ check_record_limit
197
+ ciphertext_for
198
+ clear_attribute_change
199
+ clear_attribute_changes
200
+ clear_changes_information
201
+ clear_timestamp_attributes
202
+ clear_transaction_record_state
203
+ collection_cache_versioning
204
+ column_for_attribute
205
+ committed
206
+ connection_handler
207
+ create_or_update
208
+ current_time_from_proper_timezone
209
+ custom_inspect_method_defined
210
+ custom_validation_context
211
+ decrement
212
+ decrypt
213
+ decrypt_attributes
214
+ decrypt_rich_texts
215
+ default_connection_handler
216
+ default_role
217
+ default_scope_override
218
+ default_scopes
219
+ default_shard
220
+ default_validation_context
221
+ defined_enums
222
+ delete
223
+ destroy
224
+ destroy_association_async_job
225
+ destroy_associations
226
+ destroy_row
227
+ destroyed
228
+ destroyed_by_association
229
+ destroyed_by_association=
230
+ each_counter_cached_associations
231
+ encode_with
232
+ encrypt
233
+ encrypt_attributes
234
+ encrypt_rich_texts
235
+ encryptable_rich_texts
236
+ encrypted_attribute
237
+ encrypted_attributes
238
+ encrypted_attributes=
239
+ ensure_proper_type
240
+ errors
241
+ execute_callstack_for_multiparameter_attributes
242
+ extract_callstack_for_multiparameter_attributes
243
+ find_parameter_position
244
+ forget_attribute_assignments
245
+ format_for_inspect
246
+ from_json
247
+ halted_callback_hook
248
+ has_attribute
249
+ has_changes_to_save
250
+ has_defer_touch_attrs
251
+ has_destroy_flag
252
+ has_encrypted_attributes
253
+ has_encrypted_rich_texts
254
+ has_transactional_callbacks
255
+ id
256
+ id_before_type_cast
257
+ id_for_database
258
+ id_in_database
259
+ id_was
260
+ id=
261
+ include_root_in_json
262
+ increment
263
+ init_internals
264
+ init_with
265
+ init_with_attributes
266
+ initialize_internals_callback
267
+ inspection_filter
268
+ invalid
269
+ lock
270
+ lock_optimistically
271
+ locking_enabled
272
+ logger
273
+ mark_for_destruction
274
+ marked_for_destruction
275
+ matched_attribute_method
276
+ max_updated_column_timestamp
277
+ missing_attribute
278
+ model_name
279
+ mutations_before_last_save
280
+ mutations_from_database
281
+ nested_attributes_options
282
+ nested_records_changed_for_autosave
283
+ new_record
284
+ no_touching
285
+ normalize_reflection_attribute
286
+ partial_inserts
287
+ partial_updates
288
+ perform_validations
289
+ persisted
290
+ pk_attribute
291
+ pluralize_table_names
292
+ populate_with_current_scope_attributes
293
+ previous_changes
294
+ previously_new_record
295
+ previously_persisted
296
+ primary_key_prefix_type
297
+ query_attribute
298
+ raise_nested_attributes_record_not_found
299
+ raise_validation_error
300
+ raw_timestamp_to_cache_version
301
+ read_attribute
302
+ read_attribute_before_type_cast
303
+ read_attribute_for_serialization
304
+ read_attribute_for_validation
305
+ read_store_attribute
306
+ readonly
307
+ record_timestamps
308
+ record_timestamps=
309
+ reject_new_record
310
+ reload
311
+ remember_transaction_record_state
312
+ respond_to_without_attributes
313
+ restore_attribute
314
+ restore_attributes
315
+ restore_transaction_record_state
316
+ rolledback
317
+ run_callbacks
318
+ run_validations
319
+ sanitize_for_mass_assignment
320
+ sanitize_forbidden_attributes
321
+ save
322
+ save_belongs_to_association
323
+ save_collection_association
324
+ save_has_one_association
325
+ saved_change_to_attribute
326
+ saved_changes
327
+ serializable_add_includes
328
+ serializable_attributes
329
+ serializable_hash
330
+ should_record_timestamps
331
+ signed_id
332
+ signed_id_verifier_secret
333
+ skip_time_zone_conversion_for_attributes
334
+ slice
335
+ store_accessor_for
336
+ store_full_class_name
337
+ store_full_sti_class
338
+ strict_loaded_associations
339
+ strict_loading
340
+ strict_loading_mode
341
+ strict_loading_n_plus_one_only
342
+ surreptitiously_touch
343
+ table_name_prefix
344
+ table_name_suffix
345
+ time_zone_aware_attributes
346
+ time_zone_aware_types
347
+ timestamp_attributes_for_create_in_model
348
+ timestamp_attributes_for_update_in_model
349
+ to_ary
350
+ to_gid
351
+ to_gid_param
352
+ to_global_id
353
+ to_key
354
+ to_model
355
+ to_partial_path
356
+ to_sgid
357
+ to_sgid_param
358
+ to_signed_global_id
359
+ toggle
360
+ touch
361
+ touch_deferred_attributes
362
+ touch_later
363
+ transaction
364
+ transaction_include_any_action
365
+ trigger_transactional_callbacks
366
+ type_cast_attribute_value
367
+ type_for_attribute
368
+ update
369
+ update_attribute
370
+ update_column
371
+ update_columns
372
+ valid
373
+ validate
374
+ validate_collection_association
375
+ validate_encryption_allowed
376
+ validate_single_association
377
+ validates_absence_of
378
+ validates_acceptance_of
379
+ validates_comparison_of
380
+ validates_confirmation_of
381
+ validates_exclusion_of
382
+ validates_format_of
383
+ validates_inclusion_of
384
+ validates_length_of
385
+ validates_numericality_of
386
+ validates_presence_of
387
+ validates_size_of
388
+ validates_with
389
+ validation_context
390
+ validation_context=
391
+ values_at
392
+ verify_readonly_attribute
393
+ will_be_destroyed
394
+ will_save_change_to_attribute
395
+ with_lock
396
+ with_transaction_returning_status
397
+ write_attribute
398
+ write_store_attribute
399
+ ].freeze
400
+ # rubocop:enable Metrics/CollectionLiteralLength
401
+
402
+ MSG = 'Avoid dangerous column names.'
403
+
404
+ RESTRICT_ON_SEND = [:add_column, :rename, :rename_column, *COLUMN_TYPE_METHOD_NAMES].freeze
405
+
406
+ def on_send(node)
407
+ column_name_node = column_name_node_from(node)
408
+ return false unless column_name_node
409
+ return false unless dangerous_column_name_node?(column_name_node)
410
+
411
+ add_offense(column_name_node)
412
+ end
413
+
414
+ private
415
+
416
+ def column_name_node_from(node)
417
+ case node.method_name
418
+ when :add_column, :rename
419
+ node.arguments[1]
420
+ when :rename_column
421
+ node.arguments[2]
422
+ when *COLUMN_TYPE_METHOD_NAMES
423
+ node.arguments[0]
424
+ end
425
+ end
426
+
427
+ def dangerous_column_name_node?(node)
428
+ return false unless node.respond_to?(:value)
429
+
430
+ dangerous_column_name?(node.value.to_s)
431
+ end
432
+
433
+ def dangerous_column_name?(column_name)
434
+ DANGEROUS_COLUMN_NAMES.include?(column_name)
435
+ end
436
+ end
437
+ end
438
+ end
439
+ end
@@ -22,6 +22,9 @@ module RuboCop
22
22
  # And you can set a warning for `to_time` with `AllowToTime: false`.
23
23
  # `AllowToTime` is `true` by default to prevent false positive on `DateTime` object.
24
24
  #
25
+ # @safety
26
+ # This cop's autocorrection is unsafe because it may change handling time.
27
+ #
25
28
  # @example EnforcedStyle: flexible (default)
26
29
  # # bad
27
30
  # Date.today
@@ -51,6 +54,8 @@ module RuboCop
51
54
  # # bad
52
55
  # date.to_time
53
56
  class Date < Base
57
+ extend AutoCorrector
58
+
54
59
  include ConfigurableEnforcedStyle
55
60
 
56
61
  MSG = 'Do not use `Date.%<method_called>s` without zone. Use `Time.zone.%<day>s` instead.'
@@ -92,7 +97,9 @@ module RuboCop
92
97
 
93
98
  message = format(DEPRECATED_MSG, deprecated: method[:deprecated], relevant: method[:relevant])
94
99
 
95
- add_offense(node.loc.selector, message: message)
100
+ add_offense(node.loc.selector, message: message) do |corrector|
101
+ corrector.replace(node.loc.selector, method[:relevant].to_s)
102
+ end
96
103
  end
97
104
  end
98
105
 
@@ -108,7 +115,9 @@ module RuboCop
108
115
 
109
116
  message = format(MSG, method_called: method_name, day: day)
110
117
 
111
- add_offense(node.loc.selector, message: message)
118
+ add_offense(node.loc.selector, message: message) do |corrector|
119
+ corrector.replace(node.receiver.loc.name, 'Time.zone')
120
+ end
112
121
  end
113
122
 
114
123
  def extract_method_chain(node)
@@ -130,7 +139,7 @@ module RuboCop
130
139
  end
131
140
 
132
141
  def safe_to_time?(node)
133
- return unless node.method?(:to_time)
142
+ return false unless node.method?(:to_time)
134
143
 
135
144
  if node.receiver.str_type?
136
145
  zone_regexp = /([+-][\d:]+|\dZ)\z/
@@ -24,6 +24,7 @@ module RuboCop
24
24
  include RangeHelp
25
25
  extend AutoCorrector
26
26
  include ClassSendNodeHelper
27
+ include ActiveRecordHelper
27
28
 
28
29
  MSG = "Association `%<name>s` is defined multiple times. Don't repeat associations."
29
30
 
@@ -32,6 +33,8 @@ module RuboCop
32
33
  PATTERN
33
34
 
34
35
  def on_class(class_node)
36
+ return unless active_record?(class_node.parent_class)
37
+
35
38
  offenses(class_node).each do |name, nodes|
36
39
  nodes.each do |node|
37
40
  add_offense(node, message: format(MSG, name: name)) do |corrector|
@@ -74,13 +74,13 @@ module RuboCop
74
74
  end
75
75
 
76
76
  def allowed_method?(node)
77
- return unless cop_config['AllowedMethods']
77
+ return false unless cop_config['AllowedMethods']
78
78
 
79
79
  cop_config['AllowedMethods'].include?(node.method_name.to_s)
80
80
  end
81
81
 
82
82
  def allowed_receiver?(node)
83
- return unless cop_config['AllowedReceivers'] && node.receiver
83
+ return false unless cop_config['AllowedReceivers'] && node.receiver
84
84
 
85
85
  cop_config['AllowedReceivers'].include?(node.receiver.source)
86
86
  end
@@ -88,7 +88,7 @@ module RuboCop
88
88
  # config option `WhiteList` will be deprecated soon
89
89
  def whitelisted?(node)
90
90
  whitelist_config = cop_config['Whitelist']
91
- return unless whitelist_config
91
+ return false unless whitelist_config
92
92
 
93
93
  whitelist_config.include?(node.method_name.to_s)
94
94
  end