如何在Rails中记忆类方法?

mon*_*ike 12 ruby-on-rails ruby-on-rails-3

我有一个带有类方法的模型,该方法计算量很大,每次请求都会调用很多次.

理想情况下,我想在单个请求的持续时间内缓存结果.

在这种情况下,最佳做法是什么?

例:

class MyClass < ActiveRecord::Base
  def self.heavy_method; ... ; end
end
Run Code Online (Sandbox Code Playgroud)

然后在帮手

def helper
  MyClass.heavy_method
end
Run Code Online (Sandbox Code Playgroud)

在许多视图中使用此帮助程序

Cha*_*ier 17

这是一个非常通用的解决方案,可能适合您.

class Klass
  def self.memoized_expensive_method
    @memoized_expensive_method_result ||= expensive_method
  end

  def self.expensive_method
    # ...
  end
end
Run Code Online (Sandbox Code Playgroud)

然后,如果要确保在每个请求上重新执行代码,可以在控制器中使用过滤器.

class Klass
  def self.reset_expensive_method_cache!
    @memoized_expensive_method_result = nil
  end
end

class ApplicationController
  before_filter :reset_klass_expensive_method_cache

  def reset_klass_expensive_method_cache
    Klass.reset_expensive_method_cache!
  end
end
Run Code Online (Sandbox Code Playgroud)

请注意,在类变量中存储内容可能会导致线程安全问题,因为缓存的结果将在线程之间共享.

如果这可能是您的应用程序的问题,您可能希望将数据存储在线程中而不是使用类变量.

  • 值得注意的是,您可能会使用具有多个线程的 Web 服务器。不同线程上同时发生的两个请求将竞争并争夺缓存。不建议使用此解决方案来缓存每个请求。[RequestStore](https://github.com/steveklabnik/request_store) gem 是线程安全的 (2认同)