My understanding is that strict loading should be enabled app-wide when adding self.strict_loading_by_default = true
to ApplicationRecord
. However I silently still get N+1’s with the example below. Would someone have insight into how to enforce strict loading?
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
self.strict_loading_by_default = true
end
class ModuleSession < ApplicationRecord
has_many :viewerships, as: :record, dependent: :destroy
scope :with_viewerships, ->(user) {
# BTW is there any cleaner way to load the user's viewerships?
joins("LEFT JOIN viewerships "\
"ON viewerships.record_type = 'ModuleSession' "\
"AND viewerships.record_id = module_sessions.id AND "\
"viewerships.user_id = #{user.id}")
.includes(:viewerships)
}
end
class Viewership < ApplicationRecord
belongs_to :user, inverse_of: :viewerships
belongs_to :record, polymorphic: true
end
class CourseModulesController < ApplicationController
def show
ModuleSession.with_viewerships(current_user).each do |s|
s.viewerships.find_or_initialize_by(user: current_user)
# s.viewerships.first_or_initialize(user: current_user)
end
end
end
When calling the above controller action, a bunch of SQL “Viewership Load” are triggered, see screenshot from rack-mini-profiler
:
The N+1 queries disappear when find_or_initialize_by
is replaced with first_or_initialize
(I don’t know why, but it’s good news). I would have expected a strict loading error to be raised so that I become aware of this problem and can correct it.