15

リクエストごとに何度も呼び出す計算が重いクラスメソッドを持つモデルがあります。

理想的には、単一のリクエストの間、結果をキャッシュしたいと思います。

この状況でのレールのベストプラクティスは何ですか?

例:

class MyClass < ActiveRecord::Base
  def self.heavy_method; ... ; end
end

次に、ヘルパーで

def helper
  MyClass.heavy_method
end

このヘルパーは多くのビューで使用されています

4

2 に答える 2

19

これは、あなたに役立つ可能性のある非常に一般的なソリューションです。

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

  def self.expensive_method
    # ...
  end
end

次に、リクエストごとにコードが再実行されるようにしたい場合は、コントローラーでフィルターを使用できます。

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

クラス変数に何かを格納すると、キャッシュされた結果がスレッド間で共有されるため、スレッドセーフの問題が発生する可能性があることに注意してください。

これがアプリケーションの問題になる可能性がある場合は、クラス変数を使用する代わりにスレッドにデータを格納することをお勧めします。

于 2013-04-21T15:15:39.290 に答える
3

@unixcharlesのおかげで、これが私がやり終えたことです

class SomeClass
  @lock = Mutex.new

  after_save :clear_cached_calculation

  class << self
    def some_calculation
      @lock.synchronize do
        @calc ||= heavy_operation
      end
    end

    def clear_calculation
      @lock.synchronize do
        @calc = nil
      end
    end

  end

private

  def clear_cached_caculation
    SomeClass.clear_calculation
  end
end

編集:

Rails.cache.fetch値をメモリに保持するのではなく、おそらくより良い解決策です。

于 2013-04-21T18:37:11.637 に答える