1

キャッシングは私のビューコードの中で最もロジックを集中的に使用する部分なので、デコレータ内からフラグメントキャッシングを実行したいのですが、実行できません。

デコレータからこれを行うと:

def cached_name
  h.cache do
   "a name here"
  end
end

私はこれを手に入れます:

あなたはそれを予期していなかったときにnilオブジェクトを持っています!配列のインスタンスを期待していたかもしれません。nil.lengthの評価中にエラーが発生しました

コントローラ内からデコレータをインスタンス化します

@presenter = SomePresenter::new

ビューにHAMLを使用しています

デコレータの内部からキャッシュを成功させるにはどうすればよいので、私のビューはこのようなことを行うことができます

= @decorator.cached_logic_heavy_stuff

更新:問題を示すgitリポジトリを作成しました:https ://github.com/houen/presenter_caching

更新:これはおそらく機能します-リポジトリを参照してください

  include Haml::Helpers
  def another_way_to_try
    self.init_haml_helpers
    buffer = haml_buffer.buffer

    h.with_output_buffer(buffer) do
      h.cache do
        h.concat "i should still not be empty"
      end
    end
  end
4

4 に答える 4

2

Rails.cache直接使用することで問題が解決する可能性があることをお勧めします。Rails4のデコレータでも同じことを行います。

def cached_name
  Rails.cache.fetch(source) do
    source.name # etc.
  end
end
于 2013-08-08T14:16:03.447 に答える
1

Draperを使用している場合は、ビューコンテキストを明示的に渡す必要はないと思います。インスタンス化するときに、モデルまたはコレクションをドレーパーの存在に渡すことをお勧めします。例:

class UserDecorator < Draper::Base
  decorates :user

  # additional methods
end

# in the controller
@presenter = UserDecorator.new(@user)       # for an instance
@presenter = UserDecorator.decorate(@users) # for a collection

発生しているnilオブジェクトエラーは、コードにリストされていない別のメソッド呼び出しから発生していると思われます。

デコレータからのフラグメントキャッシングに関しては、concatヘルパーメソッドを使用してこれをデコレータ内で機能させることができます。

# your decorator class
def cached_name
  h.cache("some_cache_key") do
    h.concat "a name here"
  end
end
于 2012-09-22T15:05:06.680 に答える
0

Railsのcacheメソッドは、呼び出し元のビューに基づいてキャッシュキーを推測しようとします。ビューから(デコレータクラスのインスタンス内から)実際に呼び出しているのではないので、キャッシュキーを作成しようとすると爆撃されると思います。

を介して、キャッシュキーを明示的に渡してみてくださいh.cache "your cache key" do。フルスタックトレースを使用すると、例外がスローされている場所を特定し、それを回避することもできます。ただし、完全なスタックトレースがないと、支援するのは困難です。

編集:Railsのキャッシングコードを見ると、これはもっと深い問題かもしれないと思います。の長さを取得しようとしていoutput_bufferますが、ビューのコンテキスト外(つまり、Draper内)では使用できません。次を追加してみてください。

def output_buffer
  h.output_buffer
end

しかし、それをテストしないと、もう少し作業をしなければ、計画どおりに機能しない可能性があると思います。これは大まかな推測です。これが実際に問題である場合は驚きますが、うまくいけば、正しい方向に進むことができます。

そこのソースのメモ:

# VIEW TODO: Make #capture usable outside of ERB
# This dance is needed because Builder can't use capture

これは完全に解決された問題ではないことを示しているため、これを機能させるには、Railsの内部を少し掘り下げる必要があるかもしれません。

于 2012-09-22T15:27:21.187 に答える
0

これは機能します:

  include Haml::Helpers
  def another_way_to_try
    self.init_haml_helpers
    buffer = haml_buffer.buffer
    h.with_output_buffer(buffer) do
      h.cache "some_key10", :expires_in => 10.seconds do
        h.concat "i should still not be empty 2"
      end
    end
  end
于 2012-09-22T15:52:04.203 に答える