rubocop-rails 2.7.1 → 2.10.0

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 (102) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +18 -2
  4. data/config/default.yml +144 -6
  5. data/config/obsoletion.yml +7 -0
  6. data/lib/rubocop/cop/mixin/active_record_helper.rb +16 -3
  7. data/lib/rubocop/cop/mixin/enforce_superclass.rb +40 -0
  8. data/lib/rubocop/cop/mixin/index_method.rb +25 -11
  9. data/lib/rubocop/cop/rails/action_filter.rb +10 -14
  10. data/lib/rubocop/cop/rails/active_record_aliases.rb +13 -17
  11. data/lib/rubocop/cop/rails/active_record_callbacks_order.rb +19 -16
  12. data/lib/rubocop/cop/rails/active_record_override.rb +1 -1
  13. data/lib/rubocop/cop/rails/active_support_aliases.rb +12 -21
  14. data/lib/rubocop/cop/rails/after_commit_override.rb +91 -0
  15. data/lib/rubocop/cop/rails/application_controller.rb +3 -7
  16. data/lib/rubocop/cop/rails/application_job.rb +2 -1
  17. data/lib/rubocop/cop/rails/application_mailer.rb +2 -7
  18. data/lib/rubocop/cop/rails/application_record.rb +2 -7
  19. data/lib/rubocop/cop/rails/arel_star.rb +41 -0
  20. data/lib/rubocop/cop/rails/assert_not.rb +8 -10
  21. data/lib/rubocop/cop/rails/attribute_default_block_value.rb +90 -0
  22. data/lib/rubocop/cop/rails/belongs_to.rb +10 -19
  23. data/lib/rubocop/cop/rails/blank.rb +31 -27
  24. data/lib/rubocop/cop/rails/bulk_change_table.rb +1 -1
  25. data/lib/rubocop/cop/rails/content_tag.rb +34 -19
  26. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +2 -1
  27. data/lib/rubocop/cop/rails/date.rb +10 -11
  28. data/lib/rubocop/cop/rails/default_scope.rb +11 -4
  29. data/lib/rubocop/cop/rails/delegate.rb +9 -9
  30. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +7 -8
  31. data/lib/rubocop/cop/rails/dynamic_find_by.rb +15 -12
  32. data/lib/rubocop/cop/rails/enum_hash.rb +11 -10
  33. data/lib/rubocop/cop/rails/enum_uniqueness.rb +2 -1
  34. data/lib/rubocop/cop/rails/environment_comparison.rb +18 -14
  35. data/lib/rubocop/cop/rails/environment_variable_access.rb +67 -0
  36. data/lib/rubocop/cop/rails/exit.rb +4 -10
  37. data/lib/rubocop/cop/rails/file_path.rb +7 -8
  38. data/lib/rubocop/cop/rails/find_by.rb +13 -13
  39. data/lib/rubocop/cop/rails/find_by_id.rb +12 -21
  40. data/lib/rubocop/cop/rails/find_each.rb +19 -18
  41. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +3 -2
  42. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +37 -10
  43. data/lib/rubocop/cop/rails/helper_instance_variable.rb +30 -2
  44. data/lib/rubocop/cop/rails/http_positional_arguments.rb +32 -21
  45. data/lib/rubocop/cop/rails/http_status.rb +7 -9
  46. data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +8 -6
  47. data/lib/rubocop/cop/rails/index_by.rb +11 -2
  48. data/lib/rubocop/cop/rails/index_with.rb +11 -2
  49. data/lib/rubocop/cop/rails/inquiry.rb +7 -2
  50. data/lib/rubocop/cop/rails/inverse_of.rb +3 -2
  51. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +17 -15
  52. data/lib/rubocop/cop/rails/link_to_blank.rb +25 -23
  53. data/lib/rubocop/cop/rails/mailer_name.rb +19 -13
  54. data/lib/rubocop/cop/rails/match_route.rb +14 -13
  55. data/lib/rubocop/cop/rails/negate_include.rb +10 -8
  56. data/lib/rubocop/cop/rails/not_null_column.rb +2 -1
  57. data/lib/rubocop/cop/rails/order_by_id.rb +52 -0
  58. data/lib/rubocop/cop/rails/output.rb +5 -2
  59. data/lib/rubocop/cop/rails/output_safety.rb +3 -2
  60. data/lib/rubocop/cop/rails/pick.rb +14 -12
  61. data/lib/rubocop/cop/rails/pluck.rb +6 -9
  62. data/lib/rubocop/cop/rails/pluck_id.rb +4 -6
  63. data/lib/rubocop/cop/rails/pluck_in_where.rb +39 -5
  64. data/lib/rubocop/cop/rails/pluralization_grammar.rb +10 -14
  65. data/lib/rubocop/cop/rails/presence.rb +12 -13
  66. data/lib/rubocop/cop/rails/present.rb +30 -24
  67. data/lib/rubocop/cop/rails/rake_environment.rb +8 -10
  68. data/lib/rubocop/cop/rails/read_write_attribute.rb +12 -11
  69. data/lib/rubocop/cop/rails/redundant_allow_nil.rb +29 -31
  70. data/lib/rubocop/cop/rails/redundant_foreign_key.rb +9 -12
  71. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +11 -10
  72. data/lib/rubocop/cop/rails/reflection_class_name.rb +18 -4
  73. data/lib/rubocop/cop/rails/refute_methods.rb +9 -10
  74. data/lib/rubocop/cop/rails/relative_date_constant.rb +34 -22
  75. data/lib/rubocop/cop/rails/render_inline.rb +2 -1
  76. data/lib/rubocop/cop/rails/render_plain_text.rb +9 -14
  77. data/lib/rubocop/cop/rails/request_referer.rb +7 -7
  78. data/lib/rubocop/cop/rails/require_dependency.rb +38 -0
  79. data/lib/rubocop/cop/rails/reversible_migration.rb +83 -8
  80. data/lib/rubocop/cop/rails/reversible_migration_method_definition.rb +75 -0
  81. data/lib/rubocop/cop/rails/safe_navigation.rb +30 -11
  82. data/lib/rubocop/cop/rails/safe_navigation_with_blank.rb +5 -10
  83. data/lib/rubocop/cop/rails/save_bang.rb +19 -22
  84. data/lib/rubocop/cop/rails/scope_args.rb +2 -1
  85. data/lib/rubocop/cop/rails/short_i18n.rb +7 -9
  86. data/lib/rubocop/cop/rails/skips_model_validations.rb +4 -4
  87. data/lib/rubocop/cop/rails/squished_sql_heredocs.rb +82 -0
  88. data/lib/rubocop/cop/rails/time_zone.rb +35 -25
  89. data/lib/rubocop/cop/rails/time_zone_assignment.rb +37 -0
  90. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +6 -6
  91. data/lib/rubocop/cop/rails/unique_validation_without_index.rb +18 -8
  92. data/lib/rubocop/cop/rails/unknown_env.rb +3 -3
  93. data/lib/rubocop/cop/rails/validation.rb +15 -14
  94. data/lib/rubocop/cop/rails/where_equals.rb +98 -0
  95. data/lib/rubocop/cop/rails/where_exists.rb +85 -16
  96. data/lib/rubocop/cop/rails/where_not.rb +101 -0
  97. data/lib/rubocop/cop/rails_cops.rb +12 -0
  98. data/lib/rubocop/rails.rb +2 -0
  99. data/lib/rubocop/rails/schema_loader.rb +4 -4
  100. data/lib/rubocop/rails/schema_loader/schema.rb +4 -8
  101. data/lib/rubocop/rails/version.rb +5 -1
  102. metadata +33 -14
@@ -32,7 +32,9 @@ module RuboCop
32
32
  # validates :foo, size: true
33
33
  # validates :foo, uniqueness: true
34
34
  #
35
- class Validation < Cop
35
+ class Validation < Base
36
+ extend AutoCorrector
37
+
36
38
  MSG = 'Prefer the new style validations `%<prefer>s` over ' \
37
39
  '`%<current>s`.'
38
40
 
@@ -50,22 +52,20 @@ module RuboCop
50
52
  uniqueness
51
53
  ].freeze
52
54
 
53
- DENYLIST = TYPES.map { |p| "validates_#{p}_of".to_sym }.freeze
55
+ RESTRICT_ON_SEND = TYPES.map { |p| "validates_#{p}_of".to_sym }.freeze
54
56
  ALLOWLIST = TYPES.map { |p| "validates :column, #{p}: value" }.freeze
55
57
 
56
58
  def on_send(node)
57
- return unless !node.receiver && DENYLIST.include?(node.method_name)
59
+ return if node.receiver
58
60
 
59
- add_offense(node, location: :selector)
60
- end
61
+ range = node.loc.selector
61
62
 
62
- def autocorrect(node)
63
- last_argument = node.arguments.last
64
- return if !last_argument.literal? && !last_argument.splat_type? &&
65
- !frozen_array_argument?(last_argument)
63
+ add_offense(range, message: message(node)) do |corrector|
64
+ last_argument = node.arguments.last
65
+ return if !last_argument.literal? && !last_argument.splat_type? &&
66
+ !frozen_array_argument?(last_argument)
66
67
 
67
- lambda do |corrector|
68
- corrector.replace(node.loc.selector, 'validates')
68
+ corrector.replace(range, 'validates')
69
69
  correct_validate_type(corrector, node)
70
70
  end
71
71
  end
@@ -73,12 +73,13 @@ module RuboCop
73
73
  private
74
74
 
75
75
  def message(node)
76
- format(MSG, prefer: preferred_method(node.method_name),
77
- current: node.method_name)
76
+ method_name = node.method_name
77
+
78
+ format(MSG, prefer: preferred_method(method_name), current: method_name)
78
79
  end
79
80
 
80
81
  def preferred_method(method)
81
- ALLOWLIST[DENYLIST.index(method.to_sym)]
82
+ ALLOWLIST[RESTRICT_ON_SEND.index(method.to_sym)]
82
83
  end
83
84
 
84
85
  def correct_validate_type(corrector, node)
@@ -0,0 +1,98 @@
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(attribute: value)`.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # User.where('name = ?', 'Gabe')
12
+ # User.where('name = :name', name: 'Gabe')
13
+ # User.where('name IS NULL')
14
+ # User.where('name IN (?)', ['john', 'jane'])
15
+ # User.where('name IN (:names)', names: ['john', 'jane'])
16
+ # User.where('users.name = :name', name: 'Gabe')
17
+ #
18
+ # # good
19
+ # User.where(name: 'Gabe')
20
+ # User.where(name: nil)
21
+ # User.where(name: ['john', 'jane'])
22
+ # User.where(users: { name: 'Gabe' })
23
+ class WhereEquals < Base
24
+ include RangeHelp
25
+ extend AutoCorrector
26
+
27
+ MSG = 'Use `%<good_method>s` instead of manually constructing SQL.'
28
+ RESTRICT_ON_SEND = %i[where].freeze
29
+
30
+ def_node_matcher :where_method_call?, <<~PATTERN
31
+ {
32
+ (send _ :where (array $str_type? $_ ?))
33
+ (send _ :where $str_type? $_ ?)
34
+ }
35
+ PATTERN
36
+
37
+ def on_send(node)
38
+ where_method_call?(node) do |template_node, value_node|
39
+ value_node = value_node.first
40
+
41
+ range = offense_range(node)
42
+
43
+ column_and_value = extract_column_and_value(template_node, value_node)
44
+ return unless column_and_value
45
+
46
+ good_method = build_good_method(*column_and_value)
47
+ message = format(MSG, good_method: good_method)
48
+
49
+ add_offense(range, message: message) do |corrector|
50
+ corrector.replace(range, good_method)
51
+ end
52
+ end
53
+ end
54
+
55
+ EQ_ANONYMOUS_RE = /\A([\w.]+)\s+=\s+\?\z/.freeze # column = ?
56
+ IN_ANONYMOUS_RE = /\A([\w.]+)\s+IN\s+\(\?\)\z/i.freeze # column IN (?)
57
+ EQ_NAMED_RE = /\A([\w.]+)\s+=\s+:(\w+)\z/.freeze # column = :column
58
+ IN_NAMED_RE = /\A([\w.]+)\s+IN\s+\(:(\w+)\)\z/i.freeze # column IN (:column)
59
+ IS_NULL_RE = /\A([\w.]+)\s+IS\s+NULL\z/i.freeze # column IS NULL
60
+
61
+ private
62
+
63
+ def offense_range(node)
64
+ range_between(node.loc.selector.begin_pos, node.loc.expression.end_pos)
65
+ end
66
+
67
+ def extract_column_and_value(template_node, value_node)
68
+ value =
69
+ case template_node.value
70
+ when EQ_ANONYMOUS_RE, IN_ANONYMOUS_RE
71
+ value_node.source
72
+ when EQ_NAMED_RE, IN_NAMED_RE
73
+ return unless value_node&.hash_type?
74
+
75
+ pair = value_node.pairs.find { |p| p.key.value.to_sym == Regexp.last_match(2).to_sym }
76
+ pair.value.source
77
+ when IS_NULL_RE
78
+ 'nil'
79
+ else
80
+ return
81
+ end
82
+
83
+ [Regexp.last_match(1), value]
84
+ end
85
+
86
+ def build_good_method(column, value)
87
+ if column.include?('.')
88
+ table, column = column.split('.')
89
+
90
+ "where(#{table}: { #{column}: #{value} })"
91
+ else
92
+ "where(#{column}: #{value})"
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -3,9 +3,26 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Rails
6
- # This cop enforces the use of `exists?(...)` over `where(...).exists?`.
6
+ # This cop enforces consistent style when using `exists?`.
7
7
  #
8
- # @example
8
+ # Two styles are supported for this cop. When EnforcedStyle is 'exists'
9
+ # then the cop enforces `exists?(...)` over `where(...).exists?`.
10
+ #
11
+ # When EnforcedStyle is 'where' then the cop enforces
12
+ # `where(...).exists?` over `exists?(...)`.
13
+ #
14
+ # This cop is unsafe for auto-correction because the behavior may change on the following case:
15
+ #
16
+ # [source,ruby]
17
+ # ----
18
+ # Author.includes(:articles).where(articles: {id: id}).exists?
19
+ # #=> Perform `eager_load` behavior (`LEFT JOIN` query) and get result.
20
+ #
21
+ # Author.includes(:articles).exists?(articles: {id: id})
22
+ # #=> Perform `preload` behavior and `ActiveRecord::StatementInvalid` error occurs.
23
+ # ----
24
+ #
25
+ # @example EnforcedStyle: exists (default)
9
26
  # # bad
10
27
  # User.where(name: 'john').exists?
11
28
  # User.where(['name = ?', 'john']).exists?
@@ -17,51 +34,103 @@ module RuboCop
17
34
  # User.where('length(name) > 10').exists?
18
35
  # user.posts.exists?(published: true)
19
36
  #
20
- class WhereExists < Cop
37
+ # @example EnforcedStyle: where
38
+ # # bad
39
+ # User.exists?(name: 'john')
40
+ # User.exists?(['name = ?', 'john'])
41
+ # User.exists?('name = ?', 'john')
42
+ # user.posts.exists?(published: true)
43
+ #
44
+ # # good
45
+ # User.where(name: 'john').exists?
46
+ # User.where(['name = ?', 'john']).exists?
47
+ # User.where('name = ?', 'john').exists?
48
+ # user.posts.where(published: true).exists?
49
+ # User.where('length(name) > 10').exists?
50
+ class WhereExists < Base
51
+ include ConfigurableEnforcedStyle
52
+ extend AutoCorrector
53
+
21
54
  MSG = 'Prefer `%<good_method>s` over `%<bad_method>s`.'
55
+ RESTRICT_ON_SEND = %i[exists?].freeze
22
56
 
23
57
  def_node_matcher :where_exists_call?, <<~PATTERN
24
58
  (send (send _ :where $...) :exists?)
25
59
  PATTERN
26
60
 
61
+ def_node_matcher :exists_with_args?, <<~PATTERN
62
+ (send _ :exists? $...)
63
+ PATTERN
64
+
27
65
  def on_send(node)
28
- where_exists_call?(node) do |args|
66
+ find_offenses(node) do |args|
29
67
  return unless convertable_args?(args)
30
68
 
31
69
  range = correction_range(node)
32
- message = format(MSG, good_method: build_good_method(args), bad_method: range.source)
33
- add_offense(node, location: range, message: message)
70
+ good_method = build_good_method(args)
71
+ message = format(MSG, good_method: good_method, bad_method: range.source)
72
+
73
+ add_offense(range, message: message) do |corrector|
74
+ corrector.replace(range, good_method)
75
+ end
34
76
  end
35
77
  end
36
78
 
37
- def autocorrect(node)
38
- args = where_exists_call?(node)
79
+ private
39
80
 
40
- lambda do |corrector|
41
- corrector.replace(
42
- correction_range(node),
43
- build_good_method(args)
44
- )
45
- end
81
+ def where_style?
82
+ style == :where
46
83
  end
47
84
 
48
- private
85
+ def exists_style?
86
+ style == :exists
87
+ end
88
+
89
+ def find_offenses(node, &block)
90
+ if exists_style?
91
+ where_exists_call?(node, &block)
92
+ elsif where_style?
93
+ exists_with_args?(node, &block)
94
+ end
95
+ end
49
96
 
50
97
  def convertable_args?(args)
98
+ return false if args.empty?
99
+
51
100
  args.size > 1 || args[0].hash_type? || args[0].array_type?
52
101
  end
53
102
 
54
103
  def correction_range(node)
55
- node.receiver.loc.selector.join(node.loc.selector)
104
+ if exists_style?
105
+ node.receiver.loc.selector.join(node.loc.selector)
106
+ elsif where_style?
107
+ node.loc.selector.with(end_pos: node.loc.expression.end_pos)
108
+ end
56
109
  end
57
110
 
58
111
  def build_good_method(args)
112
+ if exists_style?
113
+ build_good_method_exists(args)
114
+ elsif where_style?
115
+ build_good_method_where(args)
116
+ end
117
+ end
118
+
119
+ def build_good_method_exists(args)
59
120
  if args.size > 1
60
121
  "exists?([#{args.map(&:source).join(', ')}])"
61
122
  else
62
123
  "exists?(#{args[0].source})"
63
124
  end
64
125
  end
126
+
127
+ def build_good_method_where(args)
128
+ if args.size > 1
129
+ "where(#{args.map(&:source).join(', ')}).exists?"
130
+ else
131
+ "where(#{args[0].source}).exists?"
132
+ end
133
+ end
65
134
  end
66
135
  end
67
136
  end
@@ -0,0 +1,101 @@
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
+ # User.where('users.name != :name', name: 'Gabe')
19
+ #
20
+ # # good
21
+ # User.where.not(name: 'Gabe')
22
+ # User.where.not(name: nil)
23
+ # User.where.not(name: ['john', 'jane'])
24
+ # User.where.not(users: { name: 'Gabe' })
25
+ #
26
+ class WhereNot < Base
27
+ include RangeHelp
28
+ extend AutoCorrector
29
+
30
+ MSG = 'Use `%<good_method>s` instead of manually constructing negated SQL in `where`.'
31
+ RESTRICT_ON_SEND = %i[where].freeze
32
+
33
+ def_node_matcher :where_method_call?, <<~PATTERN
34
+ {
35
+ (send _ :where (array $str_type? $_ ?))
36
+ (send _ :where $str_type? $_ ?)
37
+ }
38
+ PATTERN
39
+
40
+ def on_send(node)
41
+ where_method_call?(node) do |template_node, value_node|
42
+ value_node = value_node.first
43
+
44
+ range = offense_range(node)
45
+
46
+ column_and_value = extract_column_and_value(template_node, value_node)
47
+ return unless column_and_value
48
+
49
+ good_method = build_good_method(*column_and_value)
50
+ message = format(MSG, good_method: good_method)
51
+
52
+ add_offense(range, message: message) do |corrector|
53
+ corrector.replace(range, good_method)
54
+ end
55
+ end
56
+ end
57
+
58
+ NOT_EQ_ANONYMOUS_RE = /\A([\w.]+)\s+(?:!=|<>)\s+\?\z/.freeze # column != ?, column <> ?
59
+ NOT_IN_ANONYMOUS_RE = /\A([\w.]+)\s+NOT\s+IN\s+\(\?\)\z/i.freeze # column NOT IN (?)
60
+ NOT_EQ_NAMED_RE = /\A([\w.]+)\s+(?:!=|<>)\s+:(\w+)\z/.freeze # column != :column, column <> :column
61
+ NOT_IN_NAMED_RE = /\A([\w.]+)\s+NOT\s+IN\s+\(:(\w+)\)\z/i.freeze # column NOT IN (:column)
62
+ IS_NOT_NULL_RE = /\A([\w.]+)\s+IS\s+NOT\s+NULL\z/i.freeze # column IS NOT NULL
63
+
64
+ private
65
+
66
+ def offense_range(node)
67
+ range_between(node.loc.selector.begin_pos, node.loc.expression.end_pos)
68
+ end
69
+
70
+ def extract_column_and_value(template_node, value_node)
71
+ value =
72
+ case template_node.value
73
+ when NOT_EQ_ANONYMOUS_RE, NOT_IN_ANONYMOUS_RE
74
+ value_node.source
75
+ when NOT_EQ_NAMED_RE, NOT_IN_NAMED_RE
76
+ return unless value_node.hash_type?
77
+
78
+ pair = value_node.pairs.find { |p| p.key.value.to_sym == Regexp.last_match(2).to_sym }
79
+ pair.value.source
80
+ when IS_NOT_NULL_RE
81
+ 'nil'
82
+ else
83
+ return
84
+ end
85
+
86
+ [Regexp.last_match(1), value]
87
+ end
88
+
89
+ def build_good_method(column, value)
90
+ if column.include?('.')
91
+ table, column = column.split('.')
92
+
93
+ "where.not(#{table}: { #{column}: #{value} })"
94
+ else
95
+ "where.not(#{column}: #{value})"
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ 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'
@@ -27,6 +31,7 @@ require_relative 'rails/dynamic_find_by'
27
31
  require_relative 'rails/enum_hash'
28
32
  require_relative 'rails/enum_uniqueness'
29
33
  require_relative 'rails/environment_comparison'
34
+ require_relative 'rails/environment_variable_access'
30
35
  require_relative 'rails/exit'
31
36
  require_relative 'rails/file_path'
32
37
  require_relative 'rails/find_by'
@@ -48,6 +53,7 @@ require_relative 'rails/mailer_name'
48
53
  require_relative 'rails/match_route'
49
54
  require_relative 'rails/negate_include'
50
55
  require_relative 'rails/not_null_column'
56
+ require_relative 'rails/order_by_id'
51
57
  require_relative 'rails/output'
52
58
  require_relative 'rails/output_safety'
53
59
  require_relative 'rails/pick'
@@ -68,16 +74,22 @@ require_relative 'rails/relative_date_constant'
68
74
  require_relative 'rails/render_inline'
69
75
  require_relative 'rails/render_plain_text'
70
76
  require_relative 'rails/request_referer'
77
+ require_relative 'rails/require_dependency'
71
78
  require_relative 'rails/reversible_migration'
79
+ require_relative 'rails/reversible_migration_method_definition'
72
80
  require_relative 'rails/safe_navigation'
73
81
  require_relative 'rails/safe_navigation_with_blank'
74
82
  require_relative 'rails/save_bang'
75
83
  require_relative 'rails/scope_args'
76
84
  require_relative 'rails/short_i18n'
77
85
  require_relative 'rails/skips_model_validations'
86
+ require_relative 'rails/squished_sql_heredocs'
78
87
  require_relative 'rails/time_zone'
88
+ require_relative 'rails/time_zone_assignment'
79
89
  require_relative 'rails/uniq_before_pluck'
80
90
  require_relative 'rails/unique_validation_without_index'
81
91
  require_relative 'rails/unknown_env'
82
92
  require_relative 'rails/validation'
93
+ require_relative 'rails/where_equals'
83
94
  require_relative 'rails/where_exists'
95
+ require_relative 'rails/where_not'