Skip to content

Commit

Permalink
Add new Rails/StrictLoadingAssociations cop
Browse files Browse the repository at this point in the history
  • Loading branch information
Drenmi committed Nov 28, 2022
1 parent c88a51d commit e77e58f
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 0 deletions.
1 change: 1 addition & 0 deletions changelog/new_add_strict_loading_associations_cop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- [#876](https://github.com/rubocop/rubocop-rails/pull/876): Add new Rails/StrictLoadingAssociations cop. ([@drenmi][])
5 changes: 5 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,11 @@ Rails/SquishedSQLHeredocs:
# to be preserved in order to work, thus autocorrection is not safe.
SafeAutoCorrect: false

Rails/StrictLoadingAssociations:
Description: 'Declare a `strict_loading` option on `has_many` associations.'
Enabled: pending
VersionAdded: '2.18'

Rails/StripHeredoc:
Description: 'Enforces the use of squiggly heredoc over `strip_heredoc`.'
StyleGuide: 'https://rails.rubystyle.guide/#prefer-squiggly-heredoc'
Expand Down
49 changes: 49 additions & 0 deletions lib/rubocop/cop/rails/strict_loading_associations.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# frozen_string_literal: true

module RuboCop
module Cop
module Rails
# Declare a `strict_loading` option on `has_many` associations.
#
# @example
#
# # bad
# has_many :posts
#
# # good
# has_many :posts, strict_loading: true
#
# # good
# has_many :posts, strict_loading: false
#
class StrictLoadingAssociations < Base
extend TargetRailsVersion

minimum_target_rails_version 6.1

MSG = 'Declare a `strict_loading` option on `has_many` associations.'

RESTRICT_ON_SEND = %i[has_many].freeze

# @!method has_many(node)
def_node_matcher :has_many, <<~PATTERN
(send nil? :has_many _ $hash ?)
PATTERN

def on_send(node)
has_many(node) do |options|
add_offense(node) unless strict_loading_declared?(options.first)
end
end

private

def strict_loading_declared?(options)
return false if options.nil?

options.each_key.any? { |k| k.value.to_s == "strict_loading" }
end
end
end
end
end
1 change: 1 addition & 0 deletions lib/rubocop/cop/rails_cops.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
require_relative 'rails/short_i18n'
require_relative 'rails/skips_model_validations'
require_relative 'rails/squished_sql_heredocs'
require_relative 'rails/strict_loading_associations'
require_relative 'rails/strip_heredoc'
require_relative 'rails/table_name_assignment'
require_relative 'rails/time_zone'
Expand Down
32 changes: 32 additions & 0 deletions spec/rubocop/cop/rails/strict_loading_associations_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::Rails::StrictLoadingAssociations, :config do
context "when using Rails 6.1 or newer", :rails61 do
it 'registers an offense when not declaring `strict_loading`' do
expect_offense(<<~RUBY)
class Author < ApplicationRecord
has_many :posts
^^^^^^^^^^^^^^^ Declare a `strict_loading` option on `has_many` associations.
end
RUBY
end

it 'does not register an offense when declaring `strict_loading`' do
expect_no_offenses(<<~RUBY)
class Author < ApplicationRecord
has_many :posts, strict_loading: true
end
RUBY
end
end

context "when using Rails 6.0 or older", :rails60 do
it 'does not register an offense when not declaring `strict_loading`' do
expect_no_offenses(<<~RUBY)
class Author < ApplicationRecord
has_many :posts
end
RUBY
end
end
end

0 comments on commit e77e58f

Please sign in to comment.