Кэширование модели со многими ассоциациями в Rails - PullRequest
2 голосов
/ 21 марта 2012

У меня есть модель с примерно 70 строками, которая является статичной (и, вероятно, будет вечной). Информация в этой таблице используется в сотнях мест на моем сайте и в моем API. Это также связано с несколькими другими моделями, которые не так малы.

Я пытаюсь найти лучший способ кэширования, чтобы избежать необходимости каждый раз обращаться к БД для доступа к ней. Я посмотрел на Redis и Memcached и понял, как я могу использовать эти инструменты. Тем не менее, я надеюсь, что есть способ сделать это без необходимости изменять все ссылки на эти данные (то есть - вызовы и ассоциации ActiveRecord). Какая моя лучшая ставка?

1 Ответ

1 голос
/ 21 марта 2012

Простой способ сделать это - просто кэшировать результаты где-нибудь в вашем классе:

class MyThing < ActiveRecord::Base
  def self.cached_all
    @cached_all ||= self.all
  end
end

Предостережение заключается в том, что если вы что-то измените, у вас не будет возможности принудительно завершить его, поэтому вам придется перезапустить серверный процесс. Для некоторых вещей это не проблема, например списки стран, часовых поясов и т. Д., Где скорость изменения очень ограничена.

Вероятно, будет лучше, если вы кешируете данные в формате, подходящем для извлечения, таком как хэш, проиндексированный по идентификатору, что упрощает использование:

class MyThing < ActiveRecord::Base
  def self.cached_all
    @cached_all ||= Hash[self.all.collect { |m| [ m.id, m ] }]
  end
end

В тех ситуациях, когда вам нужен больший контроль над кэшированием, вы можете пойти по маршруту Memcached с помощью Rails.cache. Стоит также отметить, что кэширование моделей с большим объемом данных, которые вы никогда не используете, является плохой идеей, поэтому будьте осторожны. Например, не загружайте гигантские двоичные вложения, если они не требуются.

Имейте в виду, что нет никакого волшебного способа заставить другие модели использовать этот кеш, поэтому вам придется обращаться к нему преднамеренно в каждом случае, когда в противном случае вы бы ударились в таблицу базы данных. Например:

def cached_my_thing
  MyThing.cached_all[self.my_thing_id]
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...