-
Notifications
You must be signed in to change notification settings - Fork 3
Issues with separate cached ActiveRecord code paths
Suppose we are adding separate cached code paths for some ActiveRecord methods:
-
teacher.sites
->teacher.cached_sites
-
Site.find
->Site.cached_find
-
Site.where
->Site.cached_where
Many querying methods return an ActiveRecord::Relation
. There’s no data fetching until it’s absolutely necessary. If we simply added cached methods such as teacher.cached_sites
and Site.cached_where
, we would not be able to implement lazy loading.
A common technique to avoid N+1 query:
teachers = Teacher.preload(:site).where(...)
teachers.map(&:site) # no additional queries!
Simply adding a cached_where
would bypass this optimization.
With ActiveRecord, one could have associations with a scope as follows:
belongs_to :local_site, -> { where(location: ...) }
Simply adding a cached_local_site
would not be ideal:
- It interferes with the association cache
- It does not support lazy loading
One could use inverse_of
to retrieve the same Ruby object instance using different querying methods (example). Simply adding a cached code path would bypass this functionality.
# app/models/author.rb
class Author < ActiveRecord::Base
has_many :posts, inverse_of: :author
end
External gem code could use any ActiveRecord query methods. It’s not practical to patch all the gems to use the cached ActiveRecord code path (for example, ActiveJob serializes and deserializes job arguments).