Rails has added strict loading mode to prevent lazy loading


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.