rubocop-rails 2.12.4 → 2.13.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.
- checksums.yaml +4 -4
- data/config/default.yml +34 -6
- data/lib/rubocop/cop/mixin/active_record_migrations_helper.rb +34 -0
- data/lib/rubocop/cop/rails/active_record_aliases.rb +4 -0
- data/lib/rubocop/cop/rails/application_controller.rb +5 -1
- data/lib/rubocop/cop/rails/application_job.rb +5 -1
- data/lib/rubocop/cop/rails/application_mailer.rb +5 -1
- data/lib/rubocop/cop/rails/application_record.rb +6 -1
- data/lib/rubocop/cop/rails/arel_star.rb +6 -0
- data/lib/rubocop/cop/rails/blank.rb +5 -4
- data/lib/rubocop/cop/rails/compact_blank.rb +98 -0
- data/lib/rubocop/cop/rails/content_tag.rb +2 -2
- data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +2 -7
- data/lib/rubocop/cop/rails/duration_arithmetic.rb +97 -0
- data/lib/rubocop/cop/rails/dynamic_find_by.rb +4 -0
- data/lib/rubocop/cop/rails/http_positional_arguments.rb +1 -1
- data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +8 -7
- data/lib/rubocop/cop/rails/mailer_name.rb +4 -0
- data/lib/rubocop/cop/rails/negate_include.rb +3 -2
- data/lib/rubocop/cop/rails/output.rb +4 -0
- data/lib/rubocop/cop/rails/pick.rb +7 -0
- data/lib/rubocop/cop/rails/pluck_id.rb +3 -0
- data/lib/rubocop/cop/rails/pluck_in_where.rb +7 -6
- data/lib/rubocop/cop/rails/rake_environment.rb +5 -0
- data/lib/rubocop/cop/rails/redundant_presence_validation_on_belongs_to.rb +192 -0
- data/lib/rubocop/cop/rails/reflection_class_name.rb +4 -2
- data/lib/rubocop/cop/rails/relative_date_constant.rb +3 -0
- data/lib/rubocop/cop/rails/reversible_migration.rb +1 -1
- data/lib/rubocop/cop/rails/root_join_chain.rb +72 -0
- data/lib/rubocop/cop/rails/safe_navigation_with_blank.rb +12 -3
- data/lib/rubocop/cop/rails/save_bang.rb +19 -0
- data/lib/rubocop/cop/rails/schema_comment.rb +104 -0
- data/lib/rubocop/cop/rails/squished_sql_heredocs.rb +4 -2
- data/lib/rubocop/cop/rails/time_zone.rb +3 -0
- data/lib/rubocop/cop/rails/uniq_before_pluck.rb +29 -35
- data/lib/rubocop/cop/rails/where_equals.rb +4 -0
- data/lib/rubocop/cop/rails/where_exists.rb +9 -8
- data/lib/rubocop/cop/rails_cops.rb +6 -0
- data/lib/rubocop/rails/version.rb +1 -1
- metadata +11 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f12ec262c68bd72f514b80f2140b51278a947f21726ef6307e6267eaec7df4ae
|
4
|
+
data.tar.gz: 2a09b4db338465d1904a19e8d4af871ba485e75244613299fabe473854125e4c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fbf73dc2e978bc210e2dc190b8042720f24e6e374962b2873e6c29ec989ed2a7c1b05646c22a38d57f28e753104ac40a0e592730e63703d99dbb80fc6b498651
|
7
|
+
data.tar.gz: b70e78355a3fa5b09f3a2a1603c71b16547c3f2f80c0ce7c2dbbc3c38cae0a0ca9464a50895eb54ac8ccd558c9259bf28a1e4ebebb9e3d4f05102832f178fc11
|
data/config/default.yml
CHANGED
@@ -180,6 +180,12 @@ Rails/BulkChangeTable:
|
|
180
180
|
Include:
|
181
181
|
- db/migrate/*.rb
|
182
182
|
|
183
|
+
Rails/CompactBlank:
|
184
|
+
Description: 'Checks if collection can be blank-compacted with `compact_blank`.'
|
185
|
+
Enabled: pending
|
186
|
+
Safe: false
|
187
|
+
VersionAdded: '2.13'
|
188
|
+
|
183
189
|
Rails/ContentTag:
|
184
190
|
Description: 'Use `tag.something` instead of `tag(:something)`.'
|
185
191
|
Reference:
|
@@ -245,6 +251,12 @@ Rails/DelegateAllowBlank:
|
|
245
251
|
Enabled: true
|
246
252
|
VersionAdded: '0.44'
|
247
253
|
|
254
|
+
Rails/DurationArithmetic:
|
255
|
+
Description: 'Do not use duration as arithmetic operand with `Time.current`.'
|
256
|
+
StyleGuide: 'https://rails.rubystyle.guide#duration-arithmetic'
|
257
|
+
Enabled: pending
|
258
|
+
VersionAdded: '2.13'
|
259
|
+
|
248
260
|
Rails/DynamicFindBy:
|
249
261
|
Description: 'Use `find_by` instead of dynamic `find_by_*`.'
|
250
262
|
StyleGuide: 'https://rails.rubystyle.guide#find_by'
|
@@ -612,6 +624,11 @@ Rails/RedundantForeignKey:
|
|
612
624
|
Enabled: true
|
613
625
|
VersionAdded: '2.6'
|
614
626
|
|
627
|
+
Rails/RedundantPresenceValidationOnBelongsTo:
|
628
|
+
Description: 'Checks for redundant presence validation on belongs_to association.'
|
629
|
+
Enabled: pending
|
630
|
+
VersionAdded: '2.13'
|
631
|
+
|
615
632
|
Rails/RedundantReceiverInWithOptions:
|
616
633
|
Description: 'Checks for redundant receiver in `with_options`.'
|
617
634
|
Enabled: true
|
@@ -646,9 +663,9 @@ Rails/RefuteMethods:
|
|
646
663
|
Rails/RelativeDateConstant:
|
647
664
|
Description: 'Do not assign relative date to constants.'
|
648
665
|
Enabled: true
|
666
|
+
SafeAutoCorrect: false
|
649
667
|
VersionAdded: '0.48'
|
650
|
-
VersionChanged: '
|
651
|
-
AutoCorrect: false
|
668
|
+
VersionChanged: '2.13'
|
652
669
|
|
653
670
|
Rails/RenderInline:
|
654
671
|
Description: 'Prefer using a template over inline rendering.'
|
@@ -695,6 +712,11 @@ Rails/ReversibleMigrationMethodDefinition:
|
|
695
712
|
Include:
|
696
713
|
- db/migrate/*.rb
|
697
714
|
|
715
|
+
Rails/RootJoinChain:
|
716
|
+
Description: 'Use a single `#join` instead of chaining on `Rails.root` or `Rails.public_path`.'
|
717
|
+
Enabled: pending
|
718
|
+
VersionAdded: '2.13'
|
719
|
+
|
698
720
|
Rails/SafeNavigation:
|
699
721
|
Description: "Use Ruby's safe navigation operator (`&.`) instead of `try!`."
|
700
722
|
Enabled: true
|
@@ -727,6 +749,13 @@ Rails/SaveBang:
|
|
727
749
|
AllowedReceivers: []
|
728
750
|
SafeAutoCorrect: false
|
729
751
|
|
752
|
+
Rails/SchemaComment:
|
753
|
+
Description: >-
|
754
|
+
This cop enforces the use of the `comment` option when adding a new table or column
|
755
|
+
to the database during a migration.
|
756
|
+
Enabled: false
|
757
|
+
VersionAdded: '2.13'
|
758
|
+
|
730
759
|
Rails/ScopeArgs:
|
731
760
|
Description: 'Checks the arguments of ActiveRecord scopes.'
|
732
761
|
Enabled: true
|
@@ -789,9 +818,9 @@ Rails/TimeZone:
|
|
789
818
|
StyleGuide: 'https://rails.rubystyle.guide#time'
|
790
819
|
Reference: 'http://danilenko.org/2012/7/6/rails_timezones'
|
791
820
|
Enabled: true
|
792
|
-
|
821
|
+
SafeAutoCorrect: false
|
793
822
|
VersionAdded: '0.30'
|
794
|
-
VersionChanged: '2.
|
823
|
+
VersionChanged: '2.13'
|
795
824
|
# The value `strict` means that `Time` should be used with `zone`.
|
796
825
|
# The value `flexible` allows usage of `in_time_zone` instead of `zone`.
|
797
826
|
EnforcedStyle: flexible
|
@@ -814,13 +843,12 @@ Rails/UniqBeforePluck:
|
|
814
843
|
Description: 'Prefer the use of uniq or distinct before pluck.'
|
815
844
|
Enabled: true
|
816
845
|
VersionAdded: '0.40'
|
817
|
-
VersionChanged: '2.
|
846
|
+
VersionChanged: '2.13'
|
818
847
|
EnforcedStyle: conservative
|
819
848
|
SupportedStyles:
|
820
849
|
- conservative
|
821
850
|
- aggressive
|
822
851
|
SafeAutoCorrect: false
|
823
|
-
AutoCorrect: false
|
824
852
|
|
825
853
|
Rails/UniqueValidationWithoutIndex:
|
826
854
|
Description: 'Uniqueness validation should have a unique index on the database column.'
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# A mixin to extend cops for Active Record features
|
6
|
+
module ActiveRecordMigrationsHelper
|
7
|
+
extend NodePattern::Macros
|
8
|
+
|
9
|
+
RAILS_ABSTRACT_SCHEMA_DEFINITIONS = %i[
|
10
|
+
bigint binary boolean date datetime decimal float integer json string
|
11
|
+
text time timestamp virtual
|
12
|
+
].freeze
|
13
|
+
RAILS_ABSTRACT_SCHEMA_DEFINITIONS_HELPERS = %i[
|
14
|
+
column references belongs_to primary_key numeric
|
15
|
+
].freeze
|
16
|
+
POSTGRES_SCHEMA_DEFINITIONS = %i[
|
17
|
+
bigserial bit bit_varying cidr citext daterange hstore inet interval
|
18
|
+
int4range int8range jsonb ltree macaddr money numrange oid point line
|
19
|
+
lseg box path polygon circle serial tsrange tstzrange tsvector uuid xml
|
20
|
+
].freeze
|
21
|
+
MYSQL_SCHEMA_DEFINITIONS = %i[
|
22
|
+
blob tinyblob mediumblob longblob tinytext mediumtext longtext
|
23
|
+
unsigned_integer unsigned_bigint unsigned_float unsigned_decimal
|
24
|
+
].freeze
|
25
|
+
|
26
|
+
def_node_matcher :create_table_with_block?, <<~PATTERN
|
27
|
+
(block
|
28
|
+
(send nil? :create_table ...)
|
29
|
+
(args (arg _var))
|
30
|
+
_)
|
31
|
+
PATTERN
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -6,6 +6,10 @@ module RuboCop
|
|
6
6
|
# Checks that ActiveRecord aliases are not used. The direct method names
|
7
7
|
# are more clear and easier to read.
|
8
8
|
#
|
9
|
+
# @safety
|
10
|
+
# This cop is unsafe because custom `update_attributes` method call was changed to
|
11
|
+
# `update` but the method name remained same in the method definition.
|
12
|
+
#
|
9
13
|
# @example
|
10
14
|
# #bad
|
11
15
|
# book.update_attributes!(author: 'Alice')
|
@@ -3,7 +3,11 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Rails
|
6
|
-
# This cop checks that controllers subclass ApplicationController
|
6
|
+
# This cop checks that controllers subclass `ApplicationController`.
|
7
|
+
#
|
8
|
+
# @safety
|
9
|
+
# This cop's autocorrection is unsafe because it may let the logic from `ApplicationController`
|
10
|
+
# sneak into a controller that is not purposed to inherit logic common among other controllers.
|
7
11
|
#
|
8
12
|
# @example
|
9
13
|
#
|
@@ -3,7 +3,11 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Rails
|
6
|
-
# This cop checks that jobs subclass ApplicationJob with Rails 5.0.
|
6
|
+
# This cop checks that jobs subclass `ApplicationJob` with Rails 5.0.
|
7
|
+
#
|
8
|
+
# @safety
|
9
|
+
# This cop's autocorrection is unsafe because it may let the logic from `ApplicationJob`
|
10
|
+
# sneak into a job that is not purposed to inherit logic common among other jobs.
|
7
11
|
#
|
8
12
|
# @example
|
9
13
|
#
|
@@ -3,7 +3,11 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Rails
|
6
|
-
# This cop checks that mailers subclass ApplicationMailer with Rails 5.0.
|
6
|
+
# This cop checks that mailers subclass `ApplicationMailer` with Rails 5.0.
|
7
|
+
#
|
8
|
+
# @safety
|
9
|
+
# This cop's autocorrection is unsafe because it may let the logic from `ApplicationMailer`
|
10
|
+
# sneak into a mailer that is not purposed to inherit logic common among other mailers.
|
7
11
|
#
|
8
12
|
# @example
|
9
13
|
#
|
@@ -3,7 +3,12 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Rails
|
6
|
-
# This cop checks that models subclass ApplicationRecord with Rails 5.0.
|
6
|
+
# This cop checks that models subclass `ApplicationRecord` with Rails 5.0.
|
7
|
+
#
|
8
|
+
# @safety
|
9
|
+
# This cop's autocorrection is unsafe because it may let the logic from `ApplicationRecord`
|
10
|
+
# sneak into an Active Record model that is not purposed to inherit logic common among other
|
11
|
+
# Active Record models.
|
7
12
|
#
|
8
13
|
# @example
|
9
14
|
#
|
@@ -10,6 +10,12 @@ module RuboCop
|
|
10
10
|
# database to look for a column named <tt>`*`</tt> (or `"*"`) as opposed
|
11
11
|
# to expanding the column list as one would likely expect.
|
12
12
|
#
|
13
|
+
# @safety
|
14
|
+
# This cop's autocorrection is unsafe because it turns a quoted `*` into
|
15
|
+
# an SQL `*`, unquoted. `*` is a valid column name in certain databases
|
16
|
+
# supported by Rails, and even though it is usually a mistake,
|
17
|
+
# it might denote legitimate access to a column named `*`.
|
18
|
+
#
|
13
19
|
# @example
|
14
20
|
# # bad
|
15
21
|
# MyTable.arel_table["*"]
|
@@ -6,15 +6,16 @@ module RuboCop
|
|
6
6
|
# This cop checks for code that can be written with simpler conditionals
|
7
7
|
# using `Object#blank?` defined by Active Support.
|
8
8
|
#
|
9
|
-
# This cop is marked as unsafe auto-correction, because `' '.empty?` returns false,
|
10
|
-
# but `' '.blank?` returns true. Therefore, auto-correction is not compatible
|
11
|
-
# if the receiver is a non-empty blank string, tab, or newline meta characters.
|
12
|
-
#
|
13
9
|
# Interaction with `Style/UnlessElse`:
|
14
10
|
# The configuration of `NotPresent` will not produce an offense in the
|
15
11
|
# context of `unless else` if `Style/UnlessElse` is inabled. This is
|
16
12
|
# to prevent interference between the auto-correction of the two cops.
|
17
13
|
#
|
14
|
+
# @safety
|
15
|
+
# This cop is unsafe auto-correction, because `' '.empty?` returns false,
|
16
|
+
# but `' '.blank?` returns true. Therefore, auto-correction is not compatible
|
17
|
+
# if the receiver is a non-empty blank string, tab, or newline meta characters.
|
18
|
+
#
|
18
19
|
# @example NilOrEmpty: true (default)
|
19
20
|
# # Converts usages of `nil? || empty?` to `blank?`
|
20
21
|
#
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Rails
|
6
|
+
# Checks if collection can be blank-compacted with `compact_blank`.
|
7
|
+
#
|
8
|
+
# @safety
|
9
|
+
# It is unsafe by default because false positives may occur in the
|
10
|
+
# blank check of block arguments to the receiver object.
|
11
|
+
#
|
12
|
+
# For example, `[[1, 2], [3, nil]].reject { |first, second| second.blank? }` and
|
13
|
+
# `[[1, 2], [3, nil]].compact_blank` are not compatible. The same is true for `empty?`.
|
14
|
+
# This will work fine when the receiver is a hash object.
|
15
|
+
#
|
16
|
+
# @example
|
17
|
+
#
|
18
|
+
# # bad
|
19
|
+
# collection.reject(&:blank?)
|
20
|
+
# collection.reject(&:empty?)
|
21
|
+
# collection.reject { |_k, v| v.blank? }
|
22
|
+
# collection.reject { |_k, v| v.empty? }
|
23
|
+
#
|
24
|
+
# # good
|
25
|
+
# collection.compact_blank
|
26
|
+
#
|
27
|
+
# # bad
|
28
|
+
# collection.reject!(&:blank?)
|
29
|
+
# collection.reject!(&:empty?)
|
30
|
+
# collection.reject! { |_k, v| v.blank? }
|
31
|
+
# collection.reject! { |_k, v| v.empty? }
|
32
|
+
#
|
33
|
+
# # good
|
34
|
+
# collection.compact_blank!
|
35
|
+
#
|
36
|
+
class CompactBlank < Base
|
37
|
+
include RangeHelp
|
38
|
+
extend AutoCorrector
|
39
|
+
extend TargetRailsVersion
|
40
|
+
|
41
|
+
MSG = 'Use `%<preferred_method>s` instead.'
|
42
|
+
RESTRICT_ON_SEND = %i[reject reject!].freeze
|
43
|
+
|
44
|
+
minimum_target_rails_version 6.1
|
45
|
+
|
46
|
+
def_node_matcher :reject_with_block?, <<~PATTERN
|
47
|
+
(block
|
48
|
+
(send _ {:reject :reject!})
|
49
|
+
$(args ...)
|
50
|
+
(send
|
51
|
+
$(lvar _) {:blank? :empty?}))
|
52
|
+
PATTERN
|
53
|
+
|
54
|
+
def_node_matcher :reject_with_block_pass?, <<~PATTERN
|
55
|
+
(send _ {:reject :reject!}
|
56
|
+
(block_pass
|
57
|
+
(sym {:blank? :empty?})))
|
58
|
+
PATTERN
|
59
|
+
|
60
|
+
def on_send(node)
|
61
|
+
return unless bad_method?(node)
|
62
|
+
|
63
|
+
range = offense_range(node)
|
64
|
+
preferred_method = preferred_method(node)
|
65
|
+
add_offense(range, message: format(MSG, preferred_method: preferred_method)) do |corrector|
|
66
|
+
corrector.replace(range, preferred_method)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def bad_method?(node)
|
73
|
+
return true if reject_with_block_pass?(node)
|
74
|
+
|
75
|
+
if (arguments, receiver_in_block = reject_with_block?(node.parent))
|
76
|
+
return arguments.length == 1 || use_hash_value_block_argument?(arguments, receiver_in_block)
|
77
|
+
end
|
78
|
+
|
79
|
+
false
|
80
|
+
end
|
81
|
+
|
82
|
+
def use_hash_value_block_argument?(arguments, receiver_in_block)
|
83
|
+
arguments.length == 2 && arguments[1].source == receiver_in_block.source
|
84
|
+
end
|
85
|
+
|
86
|
+
def offense_range(node)
|
87
|
+
end_pos = node.parent&.block_type? ? node.parent.loc.expression.end_pos : node.loc.expression.end_pos
|
88
|
+
|
89
|
+
range_between(node.loc.selector.begin_pos, end_pos)
|
90
|
+
end
|
91
|
+
|
92
|
+
def preferred_method(node)
|
93
|
+
node.method?(:reject) ? 'compact_blank' : 'compact_blank!'
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -6,8 +6,8 @@ module RuboCop
|
|
6
6
|
# This cop checks legacy syntax usage of `tag`
|
7
7
|
#
|
8
8
|
# NOTE: Allow `tag` when the first argument is a variable because
|
9
|
-
#
|
10
|
-
#
|
9
|
+
# `tag(name)` is simpler rather than `tag.public_send(name)`.
|
10
|
+
# And this cop will be renamed to something like `LegacyTag` in the future. (e.g. RuboCop Rails 2.0)
|
11
11
|
#
|
12
12
|
# @example
|
13
13
|
# # bad
|
@@ -41,16 +41,11 @@ module RuboCop
|
|
41
41
|
# t.datetime :updated_at, default: -> { 'CURRENT_TIMESTAMP' }
|
42
42
|
# end
|
43
43
|
class CreateTableWithTimestamps < Base
|
44
|
+
include ActiveRecordMigrationsHelper
|
45
|
+
|
44
46
|
MSG = 'Add timestamps when creating a new table.'
|
45
47
|
RESTRICT_ON_SEND = %i[create_table].freeze
|
46
48
|
|
47
|
-
def_node_matcher :create_table_with_block?, <<~PATTERN
|
48
|
-
(block
|
49
|
-
(send nil? :create_table ...)
|
50
|
-
(args (arg _var))
|
51
|
-
_)
|
52
|
-
PATTERN
|
53
|
-
|
54
49
|
def_node_matcher :create_table_with_timestamps_proc?, <<~PATTERN
|
55
50
|
(send nil? :create_table (sym _) ... (block-pass (sym :timestamps)))
|
56
51
|
PATTERN
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Rails
|
6
|
+
# This cop checks if a duration is added to or subtracted from `Time.current`.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # bad
|
10
|
+
# Time.current - 1.minute
|
11
|
+
# Time.current + 2.days
|
12
|
+
#
|
13
|
+
# # good - using relative would make it harder to express and read
|
14
|
+
# Date.yesterday + 3.days
|
15
|
+
# created_at - 1.minute
|
16
|
+
# 3.days - 1.hour
|
17
|
+
#
|
18
|
+
# # good
|
19
|
+
# 1.minute.ago
|
20
|
+
# 2.days.from_now
|
21
|
+
class DurationArithmetic < Base
|
22
|
+
extend AutoCorrector
|
23
|
+
|
24
|
+
MSG = 'Do not add or subtract duration.'
|
25
|
+
|
26
|
+
RESTRICT_ON_SEND = %i[+ -].freeze
|
27
|
+
|
28
|
+
DURATIONS = Set[:second, :seconds, :minute, :minutes, :hour, :hours,
|
29
|
+
:day, :days, :week, :weeks, :fortnight, :fortnights]
|
30
|
+
|
31
|
+
# @!method duration_arithmetic_argument?(node)
|
32
|
+
# Match duration subtraction or addition with current time.
|
33
|
+
#
|
34
|
+
# @example source that matches
|
35
|
+
# Time.current - 1.hour
|
36
|
+
#
|
37
|
+
# @example source that matches
|
38
|
+
# ::Time.zone.now + 1.hour
|
39
|
+
#
|
40
|
+
# @param node [RuboCop::AST::Node]
|
41
|
+
# @yield operator and duration
|
42
|
+
def_node_matcher :duration_arithmetic_argument?, <<~PATTERN
|
43
|
+
(send #time_current? ${ :+ :- } $#duration?)
|
44
|
+
PATTERN
|
45
|
+
|
46
|
+
# @!method duration?(node)
|
47
|
+
# Match a literal Duration
|
48
|
+
#
|
49
|
+
# @example source that matches
|
50
|
+
# 1.hour
|
51
|
+
#
|
52
|
+
# @example source that matches
|
53
|
+
# 9.5.weeks
|
54
|
+
#
|
55
|
+
# @param node [RuboCop::AST::Node]
|
56
|
+
# @return [Boolean] true if matches
|
57
|
+
def_node_matcher :duration?, '(send { int float (send nil _) } DURATIONS)'
|
58
|
+
|
59
|
+
# @!method time_current?(node)
|
60
|
+
# Match Time.current
|
61
|
+
#
|
62
|
+
# @example source that matches
|
63
|
+
# Time.current
|
64
|
+
#
|
65
|
+
# @example source that matches
|
66
|
+
# ::Time.zone.now
|
67
|
+
#
|
68
|
+
# @param node [RuboCop::AST::Node]
|
69
|
+
# @return [Boolean] true if matches
|
70
|
+
def_node_matcher :time_current?, <<~PATTERN
|
71
|
+
{
|
72
|
+
(send (const _ :Time) :current)
|
73
|
+
(send (send (const _ :Time) :zone) :now)
|
74
|
+
}
|
75
|
+
PATTERN
|
76
|
+
|
77
|
+
def on_send(node)
|
78
|
+
duration_arithmetic_argument?(node) do |*operation|
|
79
|
+
add_offense(node) do |corrector|
|
80
|
+
corrector.replace(node.source_range, corrected_source(*operation))
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def corrected_source(operator, duration)
|
88
|
+
if operator == :-
|
89
|
+
"#{duration.source}.ago"
|
90
|
+
else
|
91
|
+
"#{duration.source}.from_now"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -7,6 +7,10 @@ module RuboCop
|
|
7
7
|
# Use `find_by` instead of dynamic method.
|
8
8
|
# See. https://rails.rubystyle.guide#find_by
|
9
9
|
#
|
10
|
+
# @safety
|
11
|
+
# It is certainly unsafe when not configured properly, i.e. user-defined `find_by_xxx`
|
12
|
+
# method is not added to cop's `AllowedMethods`.
|
13
|
+
#
|
10
14
|
# @example
|
11
15
|
# # bad
|
12
16
|
# User.find_by_name(name)
|
@@ -67,7 +67,7 @@ module RuboCop
|
|
67
67
|
private
|
68
68
|
|
69
69
|
def in_routing_block?(node)
|
70
|
-
!!node.each_ancestor(:block).detect { |block| ROUTING_METHODS.include?(block.
|
70
|
+
!!node.each_ancestor(:block).detect { |block| ROUTING_METHODS.include?(block.method_name) }
|
71
71
|
end
|
72
72
|
|
73
73
|
def needs_conversion?(data)
|
@@ -6,13 +6,14 @@ module RuboCop
|
|
6
6
|
# This cop checks that methods specified in the filter's `only` or
|
7
7
|
# `except` options are defined within the same class or module.
|
8
8
|
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
9
|
+
# @safety
|
10
|
+
# You can technically specify methods of superclass or methods added by
|
11
|
+
# mixins on the filter, but these can confuse developers. If you specify
|
12
|
+
# methods that are defined in other classes or modules, you should
|
13
|
+
# define the filter in that class or module.
|
14
|
+
#
|
15
|
+
# If you rely on behaviour defined in the superclass actions, you must
|
16
|
+
# remember to invoke `super` in the subclass actions.
|
16
17
|
#
|
17
18
|
# @example
|
18
19
|
# # bad
|
@@ -8,6 +8,10 @@ module RuboCop
|
|
8
8
|
# Without the `Mailer` suffix it isn't immediately apparent what's a mailer
|
9
9
|
# and which views are related to the mailer.
|
10
10
|
#
|
11
|
+
# @safety
|
12
|
+
# This cop's autocorrection is unsafe because renaming a constant is
|
13
|
+
# always an unsafe operation.
|
14
|
+
#
|
11
15
|
# @example
|
12
16
|
# # bad
|
13
17
|
# class User < ActionMailer::Base
|
@@ -6,8 +6,9 @@ module RuboCop
|
|
6
6
|
# This cop enforces the use of `collection.exclude?(obj)`
|
7
7
|
# over `!collection.include?(obj)`.
|
8
8
|
#
|
9
|
-
#
|
10
|
-
#
|
9
|
+
# @safety
|
10
|
+
# This cop is unsafe because false positive will occur for
|
11
|
+
# receiver objects that do not have an `exclude?` method. (e.g. `IPAddr`)
|
11
12
|
#
|
12
13
|
# @example
|
13
14
|
# # bad
|
@@ -5,6 +5,10 @@ module RuboCop
|
|
5
5
|
module Rails
|
6
6
|
# This cop checks for the use of output calls like puts and print
|
7
7
|
#
|
8
|
+
# @safety
|
9
|
+
# This cop's autocorrection is unsafe because depending on the Rails log level configuration,
|
10
|
+
# changing from `puts` to `Rails.logger.debug` could result in no output being shown.
|
11
|
+
#
|
8
12
|
# @example
|
9
13
|
# # bad
|
10
14
|
# puts 'A debug message'
|
@@ -9,6 +9,13 @@ module RuboCop
|
|
9
9
|
# `pick` avoids. When called on an Active Record relation, `pick` adds a
|
10
10
|
# limit to the query so that only one value is fetched from the database.
|
11
11
|
#
|
12
|
+
# @safety
|
13
|
+
# This cop is unsafe because `pluck` is defined on both `ActiveRecord::Relation` and `Enumerable`,
|
14
|
+
# whereas `pick` is only defined on `ActiveRecord::Relation` in Rails 6.0. This was addressed
|
15
|
+
# in Rails 6.1 via rails/rails#38760, at which point the cop is safe.
|
16
|
+
#
|
17
|
+
# See: https://github.com/rubocop/rubocop-rails/pull/249
|
18
|
+
#
|
12
19
|
# @example
|
13
20
|
# # bad
|
14
21
|
# Model.pluck(:a).first
|
@@ -9,14 +9,15 @@ module RuboCop
|
|
9
9
|
# Since `pluck` is an eager method and hits the database immediately,
|
10
10
|
# using `select` helps to avoid additional database queries.
|
11
11
|
#
|
12
|
-
# This cop has two different enforcement modes. When the EnforcedStyle
|
13
|
-
# is conservative (the default) then only calls to `pluck` on a constant
|
12
|
+
# This cop has two different enforcement modes. When the `EnforcedStyle`
|
13
|
+
# is `conservative` (the default) then only calls to `pluck` on a constant
|
14
14
|
# (i.e. a model class) in the `where` is used as offenses.
|
15
15
|
#
|
16
|
-
#
|
17
|
-
# `
|
18
|
-
#
|
19
|
-
# `
|
16
|
+
# @safety
|
17
|
+
# When the `EnforcedStyle` is `aggressive` then all calls to `pluck` in the
|
18
|
+
# `where` is used as offenses. This may lead to false positives
|
19
|
+
# as the cop cannot replace to `select` between calls to `pluck` on an
|
20
|
+
# `ActiveRecord::Relation` instance vs a call to `pluck` on an `Array` instance.
|
20
21
|
#
|
21
22
|
# @example
|
22
23
|
# # bad
|
@@ -14,6 +14,11 @@ module RuboCop
|
|
14
14
|
# * The task does not need application code.
|
15
15
|
# * The task invokes the `:environment` task.
|
16
16
|
#
|
17
|
+
# @safety
|
18
|
+
# Probably not a problem in most cases, but it is possible that calling `:environment` task
|
19
|
+
# will break a behavior. It's also slower. E.g. some task that only needs one gem to be
|
20
|
+
# loaded to run will run significantly faster without loading the whole application.
|
21
|
+
#
|
17
22
|
# @example
|
18
23
|
# # bad
|
19
24
|
# task :foo do
|