Skip to content

Instantly share code, notes, and snippets.

@hubertlepicki
Last active April 7, 2017 15:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hubertlepicki/27e322119248115bf023885fcf5af20d to your computer and use it in GitHub Desktop.
Save hubertlepicki/27e322119248115bf023885fcf5af20d to your computer and use it in GitHub Desktop.
Simple ActiveRecord query cache
class ApplicationController < ActionController::Base
...
around_action :use_request_cache, if: Proc.new {|c| request.get? }
private
def use_request_cache
RequestCache.with_cache do
yield
end
end
...
end
# Monkey-patch AR relation to use RequestsCache to fetch records
module ActiveRecord
class Relation
def records # :nodoc:
RequestCache.fetch to_sql do
load
@records
end
end
end
end
class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
def clear_query_cache
RequestCache.clear
super
end
end
module RequestCache
def self.with_cache(request_cache = {}, &block)
Thread.current[:request_cache] = request_cache
yield
ensure
RequestCache.clear
end
def self.clear
Rails.logger.debug "RequestCache: Cleared!"
Thread.current[:request_cache] = nil
end
def self.fetch key
if Thread.current[:request_cache].nil?
Rails.logger.debug "RequestCache: Disabled: #{key}"
return yield
else
val = Thread.current[:request_cache][key]
if val
Rails.logger.debug "RequestCache: Hit: #{key}"
if val == :__nil__
return nil
else
return val
end
else
Rails.logger.debug "RequestCache: Miss: #{key}"
val = yield
Thread.current[:request_cache][key] = val || :__nil__
return val
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment