Skip to content

Instantly share code, notes, and snippets.

@eladmeidar
Created November 22, 2020 12:36
Show Gist options
  • Save eladmeidar/72f14c6ff5d65b71fa00e77c256486a3 to your computer and use it in GitHub Desktop.
Save eladmeidar/72f14c6ff5d65b71fa00e77c256486a3 to your computer and use it in GitHub Desktop.
Caching a method in Rails
module CachedMethod
def self.included(base)
base.class_eval do
@method_cache_validators = Hash.new(0)
extend ClassMethods
end
end
module ClassMethods
def invalidate_method_cache(method)
@method_cache_validators[method.to_sym] += 1
end
def cache_marker_for(method)
@method_cache_validators[method.to_sym]
end
def cache_methods(method, expire: 5.minutes, cache_key: lambda { |obj| return obj.cache_key } )
alias_method :"uncached_#{method}", method.to_sym
define_method("invalidate_#{method}") do
self.class.invalidate_method_cache(method)
end
define_method(method) do |args=nil|
puts "cache:#{self.class.cache_marker_for(method)}:#{self.class.name.downcase}:#{cache_key.call(self)}:#{method.to_s}:#{args.to_s}"
Rails.cache.fetch("cache:#{self.class.cache_marker_for(method)}:#{self.class.name.downcase}:#{cache_key.call(self)}:#{method.to_s}:#{args.to_s}", expires_in: expire) do
if args
send(:"uncached_#{method}", args)
else
send(:"uncached_#{method}")
end
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment