Rails 6.1 has added
strict_loading mode
to prevent lazy loading of associations.
When the strict_loading
mode is used,
the associated records will have to be eager loaded
using includes
else a ActiveRecord::StrictLoadingViolationError
will be raised.
>> p = Project.strict_loading.find_by(id: 'abe99c60-56c4-461e-bd59-63418a719e0d')
>> p.commits.to_a
=> ActiveRecord::StrictLoadingViolationError: Project is marked as strict_loading and Commit cannot be lazily loaded.
The strict loading mode cascades down from the parent and helps you catch places where eager loading would prevent N + 1.
>> p = Project.includes(:commits).strict_loading.find_by(id: 'abe99c60-56c4-461e-bd59-63418a719e0d')
>> p.commits.first.post
=> ActiveRecord::StrictLoadingViolationError: Commit is marked as strict_loading and Post cannot be lazily loaded.
The strict_loading
mode can also be declared as an option on the
association
to enforce eager loading of associated records.
class Project < ApplicationRecord
has_many :commits, strict_loading: true
end
>> p = Project.first
>> p.commits.first
=> ActiveRecord::StrictLoadingViolationError: The commits association is marked as strict_loading and cannot be lazily loaded.
>> p = Project.includes(:commits).first
>> p.commits.first
=> ...
Summary
The strict_loading
mode,
helps in avoiding N + 1
that might be otherwise missed.
Since these are now baked into Rails,
we have a better and predictable result,
unlike some issues that the bullet
gem might face.