drapergem / draper

Decorators/View-Models for Rails Applications

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Memorization with instance variables in helpers does not work

NielsKSchjoedt opened this issue · comments

I have helper which I use for caching and accessing some data for each item in a a collection in my views.

I have a helper which looks like this:

class MyHelper
  def human_name(id)
    id_to_human_name_map[id]
  end

  private

  # Should be loaded once per request and cached in memory for the duration of the current
  # request; cached in memcached for the `expires` duration.
  # returns something like: {23843 => "Name 1", 2387454387 => "Name 2"}
  def id_to_human_name_map
    # Memorizing to avoid the roundtrip to memcached more than once per request
    @id_to_human_name_map ||= begin
      Rails.cache.fetch("id_to_human_name_map", expires_in: 10.minutes) do
        #Some slow stuff I really don't wanna do for every item in my collection
      end
    end
  end
end

And a decorator like this:

class FruitDecorator < ApplicationDecorator
  def human_name
    h.human_name(id)
  end
end

The problem is however, that when I have a controller action like this:

def index
  @fruits = FruitDecorator.decorate_collection(Fruit.all)
  @fruits.each do |f|
    # This triggers rails to get a roundtrip to memcached for each item, 
    # even though I try to cache the result within the request with @id_to_human_name_map ||=
    f.human_name
  end
end

Then @id_to_human_name_map is nil for every item. So the instance variable seems to be set in the scope of a new instance of the helper every time, instead of in the scope of the entire request (controller).

Is this an intended behaviour of draper? Is there any way to avoid it?

I'm running draper 2.1.0

Any one? :-)

I was mistaken. There was nothing wrong with Draper. You can delete the issue :-)