rubocop-rails 2.12.1 → 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 +43 -8
- data/lib/rubocop/cop/mixin/active_record_migrations_helper.rb +34 -0
- data/lib/rubocop/cop/rails/active_record_aliases.rb +6 -2
- 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 +15 -8
- 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/find_each.rb +13 -0
- data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +1 -1
- 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 +4 -1
- data/lib/rubocop/cop/rails/reversible_migration.rb +11 -3
- 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/unique_validation_without_index.rb +1 -1
- 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
@@ -9,7 +9,7 @@ AllCops:
|
|
9
9
|
- bin/*
|
10
10
|
- db/schema.rb
|
11
11
|
# What version of Rails is the inspected code using? If a value is specified
|
12
|
-
# for TargetRailsVersion then it is used. Acceptable values are
|
12
|
+
# for TargetRailsVersion then it is used. Acceptable values are specified
|
13
13
|
# as a float (i.e. 5.1); the patch version of Rails should not be included.
|
14
14
|
# If TargetRailsVersion is not set, RuboCop will parse the Gemfile.lock or
|
15
15
|
# gems.locked file to find the version of Rails that has been bound to the
|
@@ -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:
|
@@ -189,6 +195,9 @@ Rails/ContentTag:
|
|
189
195
|
Enabled: true
|
190
196
|
VersionAdded: '2.6'
|
191
197
|
VersionChanged: '2.12'
|
198
|
+
# This `Exclude` config prevents false positives for `tag` calls to `has_one: tag`. No helpers are used in normal models.
|
199
|
+
Exclude:
|
200
|
+
- app/models/**/*.rb
|
192
201
|
|
193
202
|
Rails/CreateTableWithTimestamps:
|
194
203
|
Description: >-
|
@@ -198,6 +207,10 @@ Rails/CreateTableWithTimestamps:
|
|
198
207
|
VersionAdded: '0.52'
|
199
208
|
Include:
|
200
209
|
- db/migrate/*.rb
|
210
|
+
Exclude:
|
211
|
+
# Respect the `active_storage_variant_records` table of `*_create_active_storage_tables.active_storage.rb`
|
212
|
+
# auto-generated by `bin/rails active_storage:install` even if `created_at` is not specified.
|
213
|
+
- db/migrate/*_create_active_storage_tables.active_storage.rb
|
201
214
|
|
202
215
|
Rails/Date:
|
203
216
|
Description: >-
|
@@ -238,6 +251,12 @@ Rails/DelegateAllowBlank:
|
|
238
251
|
Enabled: true
|
239
252
|
VersionAdded: '0.44'
|
240
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
|
+
|
241
260
|
Rails/DynamicFindBy:
|
242
261
|
Description: 'Use `find_by` instead of dynamic `find_by_*`.'
|
243
262
|
StyleGuide: 'https://rails.rubystyle.guide#find_by'
|
@@ -605,6 +624,11 @@ Rails/RedundantForeignKey:
|
|
605
624
|
Enabled: true
|
606
625
|
VersionAdded: '2.6'
|
607
626
|
|
627
|
+
Rails/RedundantPresenceValidationOnBelongsTo:
|
628
|
+
Description: 'Checks for redundant presence validation on belongs_to association.'
|
629
|
+
Enabled: pending
|
630
|
+
VersionAdded: '2.13'
|
631
|
+
|
608
632
|
Rails/RedundantReceiverInWithOptions:
|
609
633
|
Description: 'Checks for redundant receiver in `with_options`.'
|
610
634
|
Enabled: true
|
@@ -639,9 +663,9 @@ Rails/RefuteMethods:
|
|
639
663
|
Rails/RelativeDateConstant:
|
640
664
|
Description: 'Do not assign relative date to constants.'
|
641
665
|
Enabled: true
|
666
|
+
SafeAutoCorrect: false
|
642
667
|
VersionAdded: '0.48'
|
643
|
-
VersionChanged: '
|
644
|
-
AutoCorrect: false
|
668
|
+
VersionChanged: '2.13'
|
645
669
|
|
646
670
|
Rails/RenderInline:
|
647
671
|
Description: 'Prefer using a template over inline rendering.'
|
@@ -688,6 +712,11 @@ Rails/ReversibleMigrationMethodDefinition:
|
|
688
712
|
Include:
|
689
713
|
- db/migrate/*.rb
|
690
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
|
+
|
691
720
|
Rails/SafeNavigation:
|
692
721
|
Description: "Use Ruby's safe navigation operator (`&.`) instead of `try!`."
|
693
722
|
Enabled: true
|
@@ -720,6 +749,13 @@ Rails/SaveBang:
|
|
720
749
|
AllowedReceivers: []
|
721
750
|
SafeAutoCorrect: false
|
722
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
|
+
|
723
759
|
Rails/ScopeArgs:
|
724
760
|
Description: 'Checks the arguments of ActiveRecord scopes.'
|
725
761
|
Enabled: true
|
@@ -782,9 +818,9 @@ Rails/TimeZone:
|
|
782
818
|
StyleGuide: 'https://rails.rubystyle.guide#time'
|
783
819
|
Reference: 'http://danilenko.org/2012/7/6/rails_timezones'
|
784
820
|
Enabled: true
|
785
|
-
|
821
|
+
SafeAutoCorrect: false
|
786
822
|
VersionAdded: '0.30'
|
787
|
-
VersionChanged: '2.
|
823
|
+
VersionChanged: '2.13'
|
788
824
|
# The value `strict` means that `Time` should be used with `zone`.
|
789
825
|
# The value `flexible` allows usage of `in_time_zone` instead of `zone`.
|
790
826
|
EnforcedStyle: flexible
|
@@ -807,16 +843,15 @@ Rails/UniqBeforePluck:
|
|
807
843
|
Description: 'Prefer the use of uniq or distinct before pluck.'
|
808
844
|
Enabled: true
|
809
845
|
VersionAdded: '0.40'
|
810
|
-
VersionChanged: '2.
|
846
|
+
VersionChanged: '2.13'
|
811
847
|
EnforcedStyle: conservative
|
812
848
|
SupportedStyles:
|
813
849
|
- conservative
|
814
850
|
- aggressive
|
815
851
|
SafeAutoCorrect: false
|
816
|
-
AutoCorrect: false
|
817
852
|
|
818
853
|
Rails/UniqueValidationWithoutIndex:
|
819
|
-
Description: 'Uniqueness validation should
|
854
|
+
Description: 'Uniqueness validation should have a unique index on the database column.'
|
820
855
|
Enabled: true
|
821
856
|
VersionAdded: '2.5'
|
822
857
|
Include:
|
@@ -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,12 +6,16 @@ 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')
|
12
16
|
#
|
13
17
|
# #good
|
14
|
-
#
|
18
|
+
# book.update!(author: 'Alice')
|
15
19
|
class ActiveRecordAliases < Base
|
16
20
|
extend AutoCorrector
|
17
21
|
|
@@ -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
|
@@ -33,6 +33,9 @@ module RuboCop
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def on_send(node)
|
36
|
+
return unless node.receiver.nil?
|
37
|
+
return if node.arguments.count >= 3
|
38
|
+
|
36
39
|
first_argument = node.first_argument
|
37
40
|
return if !first_argument ||
|
38
41
|
allowed_argument?(first_argument) ||
|
@@ -41,12 +44,7 @@ module RuboCop
|
|
41
44
|
preferred_method = node.first_argument.value.to_s.underscore
|
42
45
|
message = format(MSG, preferred_method: preferred_method, current_argument: first_argument.source)
|
43
46
|
|
44
|
-
|
45
|
-
autocorrect(corrector, node, preferred_method)
|
46
|
-
|
47
|
-
@corrected_nodes ||= Set.new.compare_by_identity
|
48
|
-
@corrected_nodes.add(node)
|
49
|
-
end
|
47
|
+
register_offense(node, message, preferred_method)
|
50
48
|
end
|
51
49
|
|
52
50
|
private
|
@@ -63,6 +61,15 @@ module RuboCop
|
|
63
61
|
allowed_name?(argument)
|
64
62
|
end
|
65
63
|
|
64
|
+
def register_offense(node, message, preferred_method)
|
65
|
+
add_offense(node, message: message) do |corrector|
|
66
|
+
autocorrect(corrector, node, preferred_method)
|
67
|
+
|
68
|
+
@corrected_nodes ||= Set.new.compare_by_identity
|
69
|
+
@corrected_nodes.add(node)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
66
73
|
def autocorrect(corrector, node, preferred_method)
|
67
74
|
range = correction_range(node)
|
68
75
|
|
@@ -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)
|
@@ -43,9 +43,22 @@ module RuboCop
|
|
43
43
|
private
|
44
44
|
|
45
45
|
def ignored?(node)
|
46
|
+
return true if active_model_error_where?(node.receiver)
|
47
|
+
|
46
48
|
method_chain = node.each_node(:send).map(&:method_name)
|
49
|
+
|
47
50
|
(cop_config['IgnoredMethods'].map(&:to_sym) & method_chain).any?
|
48
51
|
end
|
52
|
+
|
53
|
+
def active_model_error_where?(node)
|
54
|
+
node.method?(:where) && active_model_error?(node.receiver)
|
55
|
+
end
|
56
|
+
|
57
|
+
def active_model_error?(node)
|
58
|
+
return false if node.nil?
|
59
|
+
|
60
|
+
node.send_type? && node.method?(:errors)
|
61
|
+
end
|
49
62
|
end
|
50
63
|
end
|
51
64
|
end
|
@@ -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'
|