How to use a dynamic value for cache key with ActiveModel::Serializers (v0.10.0.rc1)

953 views Asked by At

I am using a database-driven solution for labels and translations that I would like to cache at the serializer level. Here is my serializer.

class AppLabelSerializer < ActiveModel::Serializer
  cache key: 'app_label', expires_in: 3.hours
  attributes :id, :key, :label, :label_plural

  def key
    object.app_label_dictionary.key
  end
end

The problem is that I need to cache the labels for each language, so I need to specify the language somewhere in the key. I tried this solution:

cache key: "#{scope.app_language.name}/app_label", expires_in: 3.hours

But the value of scope isn't available there for some reason.

1

There are 1 answers

2
Eli Duke On BEST ANSWER

I posted an issue on the AMS github page and went back and forth with @joaomdmoura and @groyoh until we came up with this temporary solution. It works on my end and it'll do for now until AMS makes an official decision on the best solution.

module ActiveModel
  class Serializer
    class Adapter
      def cache_key
        key = @klass._cache_key
        key = @cached_serializer.instance_exec &key if key.is_a?(Proc)
        key ? "#{key}/#{@cached_serializer.object.id}-#{@cached_serializer.object.updated_at}" : @cached_serializer.object.cache_key
      end
    end
  end
end

class AppLabelSerializer < ActiveModel::Serializer
  cache key: ->(){ "#{scope.app_language.name}/app_labels" }, expires_in: 3.hours
  attributes :id, :label, :label_plural    
end

It looks funny, but yes you just paste in that extension of the ActiveModel module right into your already existing serializer file.

NOTE: This only works with v0.10.0.rc1