Как насчет чего-то вроде:
class Class
# create a method whose return value will be cached for "cache_for" seconds
def cached_method(method,cache_for,&body)
define_method("__#{method}__".to_sym) do |*a,&b|
body.call(*a,&b)
end
class_eval(<<METHOD)
def #{method}(*a,&b)
unless @#{method}_cache && (@#{method}_expiry > Time.now)
@#{method}_cache = __#{method}__(*a,&b)
@#{method}_expiry = Time.now + #{cache_for}
end
@#{method}_cache
end
METHOD
end
end
Вы можете использовать его как:
class MyClass
cached_method(:users,60) do
User.all
end
end
Это кеширует пользователей на 60 секунд. Если вы снова вызовете users
для того же объекта через 60 или более секунд, он снова выполнит тело метода и обновит кеш.