Как использовать динамическое значение для ключа кэша с ActiveModel::Serializers (v0.10.0.rc1)

Я использую решение на основе базы данных для меток и переводов, которые я хотел бы кэшировать на уровне сериализатора. Вот мой сериализатор.

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

Проблема в том, что мне нужно кэшировать метки для каждого языка, поэтому мне нужно указать язык где-то в ключе. Я попробовал это решение:

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

Но значение scope там почему-то недоступно.


person Eli Duke    schedule 15.06.2015    source источник


Ответы (1)


Я опубликовал проблему на странице AMS github и переписывался с @joaomdmoura. и @groyoh, пока мы не придумали это временное решение. С моей стороны это работает и будет работать до тех пор, пока AMS не примет официальное решение о наилучшем решении.

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

Это выглядит забавно, но да, вы просто вставляете это расширение модуля ActiveModel прямо в уже существующий файл сериализатора.

ПРИМЕЧАНИЕ. Это работает только с версией 0.10.0.rc1.

person Eli Duke    schedule 15.06.2015
comment
Почему у вас есть как метод экземпляра для ключа, так и процедура? Оба подхода поддерживаются monkeyhack или вам нужно использовать оба? - person Christian Schlensker; 14.07.2015
comment
Вам не нужны оба. Метод key, который я определял, был просто ключевым полем в AppLabel, и мне нужно было его переопределить. Я удалил его из примера, потому что он был ненужным и запутанным. Это отвечает на ваш вопрос? - person Eli Duke; 14.07.2015