Skip to content

Commit

Permalink
Allow ignoring scopes for inverse_of cop
Browse files Browse the repository at this point in the history
With rails/rails#43358, Rails can now infer
inverse_of for associations with a scope when
`config.active_record.automatic_scope_inversing = true`.

This commit adds an `IgnoreScopes` option to the inverse_of cop allowing
us to disable the cop for scopes when the new Rails option is set to
`true`.

I considered having the default for `IgnoreScopes` change based on the
Rails version since this is the default for new Rails >= 7.0
applications, but existing applications that upgrade to 7.0 wouldn't
necessarily have the option set and in that case changing the
rubocop-rails default behavior would be a breaking change.
  • Loading branch information
composerinteralia committed Jan 11, 2022
1 parent 07cfcb4 commit bd968b1
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -519,3 +519,4 @@
[@leoarnold]: https://github.com/leoarnold
[@TonyArra]: https://github.com/TonyArra
[@tachyons]: https://github.com/tachyons
[@composerinteralia]: https://github.com/composerinteralia
1 change: 1 addition & 0 deletions changelog/new_allow_ignoring_scopes_for_inverse_of_cop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#614](https://github.com/rubocop/rubocop-rails/pull/614): Add `IgnoreScopes` config option for `Rails/InverseOf` cop. ([@composerinteralia][])
2 changes: 2 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,8 @@ Rails/Inquiry:
Rails/InverseOf:
Description: 'Checks for associations where the inverse cannot be determined automatically.'
Enabled: true
VersionChanged: '<<next>>'
IgnoreScopes: false
VersionAdded: '0.52'
Include:
- app/models/**/*.rb
Expand Down
18 changes: 17 additions & 1 deletion lib/rubocop/cop/rails/inverse_of.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,18 @@ module Rails
# has_many :physicians, through: :appointments
# end
#
# @example IgnoreScopes: false (default)
# # bad
# class Blog < ApplicationRecord
# has_many :posts, -> { order(published_at: :desc) }
# end
#
# @example IgnoreScopes: true
# # good
# class Blog < ApplicationRecord
# has_many :posts, -> { order(published_at: :desc) }
# end
#
# @see https://guides.rubyonrails.org/association_basics.html#bi-directional-associations
# @see https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#module-ActiveRecord::Associations::ClassMethods-label-Setting+Inverses
class InverseOf < Base
Expand Down Expand Up @@ -189,7 +201,7 @@ def on_send(node)
end

def scope?(arguments)
arguments.any?(&:block_type?)
!ignore_scopes? && arguments.any?(&:block_type?)
end

def options_requiring_inverse_of?(options)
Expand Down Expand Up @@ -236,6 +248,10 @@ def message(options)
SPECIFY_MSG
end
end

def ignore_scopes?
cop_config['IgnoreScopes'] == true
end
end
end
end
Expand Down
12 changes: 12 additions & 0 deletions spec/rubocop/cop/rails/inverse_of_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@ class Person
end
RUBY
end

context 'when `IgnoreScopes: true`' do
let(:cop_config) do
{ 'IgnoreScopes' => true }
end

it 'does not register an offense when not specifying `:inverse_of`' do
expect_no_offenses(
'has_many :foo, -> () { where(bar: true) }'
)
end
end
end

context 'with option preventing automatic inverse' do
Expand Down

0 comments on commit bd968b1

Please sign in to comment.