Rails strict_loading mode is 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.
This mode helps in identifying and fixing N+1 query issues by ensuring that certain associations are loaded eagerly to avoid performance bottlenecks.
class Client < ApplicationRecord
has_many :projects
endClient.strict_loading.first.projects
# raises ActiveRecord::StrictLoadingViolationErrorclass Client < ApplicationRecord
has_many :projects, strict_loading: true
endClient.first.projects
# raises ActiveRecord::StrictLoadingViolationErrorClient.includes(:projects).first.projects
Client Load (0.7ms) SELECT "clients".* FROM "clients" ORDER BY "clients"."id" ASC LIMIT $1 [["LIMIT", 1]]
Project Load (2.4ms) SELECT "projects".* FROM "projects" WHERE "projects"."client_id" = $1 [["client_id", 1]]
# =>
[#<Project:0x00000011133aaa48
id: 1,
client_id: 1,
name: "Miru",
description: "Time tracking">,
#<Project:0x0000001111f150b0
id: 2,
client_id: 1,
name: "Azure.com",
description: "Cloud Computing">
]Before
Strict loading in :n_plus_one_only mode is specifically designed to address performance issues that can arise when navigating through deeply nested associations
It allows direct loading of associations while restricting deeper traversal, preventing potential N+1 query issues and surprises related to ordering inconsistencies.
client = Client.find(1)
client.strict_loading!(mode: :n_plus_one_only)
client.projects.first
# SELECT "projects".* FROM "projects" WHERE "projects"."client_id" = $1 [["client_id", 1]] -- non-deterministic orderWhere as navigating through deeply nested associations throws error
client.projects.first.timesheets # raises ActiveRecord::StrictLoadingViolationErrorAfter
Strict loading using :n_plus_one_only does not eagerly load child associations.
With this change, child associations are no longer eagerly loaded, to match intended behavior and to prevent non-deterministic order issues caused by calling methods like first or last. As first and last don’t cause an N+1 by themselves, calling child associations will no longer raise.
It means associations are eagerly loaded and child associations are lazy loaded.
client = Client.find(1)
client.strict_loading!(mode: :n_plus_one_only)
client.projects.first
# SELECT "projects".* FROM "projects" WHERE "projects"."client_id" = $1 [["client_id", 1]] -- non-deterministic order
client.projects.first.timesheets # no longer raises errorSummary
With Strict loading, we can prevent lazy loading of associations as it raises ActiveRecord::StrictLoadingViolationError if the associated records are not eager loaded.
But With strict_loading!(mode: :n_plus_one_only), associations are eagerly loaded
and child associations are lazy loaded.
