Кэшировать все модели в таблице

Мне нужно кэшировать (и истечь) все модели в таблице.

Например, если у меня есть модель с именем «Валюта», у меня меньше 10 возможных валют. Поэтому было бы неплохо иметь:

class Currency < ActiveRecord::Base
  cache_all(:expire_in => 10.minutes)
end

так что

Currency.all
Currency.find_by_name("USD")

не должен попасть в БД.

Как вы думаете, это может быть хорошим подходом?

Кроме того, если вы считаете, что было бы лучше использовать модель, которая не поддерживается базой данных, прокомментируйте это. Обратите внимание, что я хотел бы иметь ассоциацию в стиле AR.


person Vlad Zloteanu    schedule 03.08.2009    source источник


Ответы (1)


Поскольку набор данных очень мал, вероятно, лучше всего кэшировать его в локальной памяти. Есть несколько способов сделать это, один из них — использовать мемоизацию, как я показать здесь. Однако это не самый эффективный способ, поскольку метод all и метод find_by_name будут храниться в отдельных кешах, даже если они являются одним и тем же объектом.

Альтернативой является переопределение методов кэширования объектов вручную. Что-то вроде этого.

class Currency < ActiveRecord::Base
  def self.all
    @all_cache ||= super.map(&:freeze) # freeze so you don't modify the cached objects
  end

  def self.find_by_name(name)
    all.detect { |c| c.name.to_s.downcase == name.to_s.downcase }
  end

  def self.flush_all_cache
    @all_cache = nil
  end
end

Там может быть плагин, чтобы справиться с этим для вас, но я вообще не смотрел на это.

person ryanb    schedule 03.08.2009
comment
Спасибо, Райан :). Я также нашел гем cached_model, но он кажется немного старым. Я попробую. - person Vlad Zloteanu; 04.08.2009
comment
Следует отметить, что если вы используете несколько серверов, то при изменении данных вам придется очищать кэш в памяти на всех серверах, а не только на том, на котором изменились данные. - person stephen.hanson; 18.08.2016