Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save pmarreck/2039250 to your computer and use it in GitHub Desktop.
Save pmarreck/2039250 to your computer and use it in GitHub Desktop.
Caching of model instances in Rails.cache
# We have a website with a lot of subdomains, each corresponds to a Site object, and the Site model/DB gets hit A LOT even though it rarely changes.
# We were looking at ways to optimize/cache this.
def current_site(memoize = true)
# (assumes "subdomain" and "domain" are available from URL information, this code may need to be tweaked)
@current_site = nil unless memoize
@current_site ||= Site.allocate.init_with('attributes' =>
Rails.cache.fetch("Site#{subdomain}.#{domain}") do
Site.find_by_subdomain_and_domain(domain, subdomain).attributes
end
)
end
# This will get you a fully instantiated Site object that never touched the DB.
# Then you just need an observer on Site to delete the cache if anything happens to the Site instance. Or figure out a key generation expiry method that takes into account updated_at, or whatever (but I think that would require maintaining a last_updated_at cached value for the site, plus additional fetching.)
# But in theory this would never even touch the database (unless the cache key didn't exist)
# and would only touch memcache once per request.
# And only cache Site instance attributes, and not associations.
# Note that this way of doing it was only available recently, like after Rails 3.
# There is probably a way to extend this into some kind of module that could be included in model classes to force their instances to be cached in the same way.
# I know that "allocate" is called on any Find (interestingly, "new" is never called on finds), so maybe hook into that via inheritance or other mechanism.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment