Rails для хэша запроса?
Есть ли способ кэшировать данные для запроса в Rails? Для данного запроса Rails/mongrel у меня есть результат полудорогой операции, к которой я хотел бы получить доступ несколько раз позже в этом запросе. Есть ли хэш, где я могу хранить и получать доступ к таким данным?
Он должен быть достаточно глобальным и доступным из представлений, контроллеров и библиотек, таких как Rails.cache и I18n.
Я в порядке, делаю некоторые исправления обезьян, если это нужно.
- Memcached не работает, потому что он будет разделяться между запросами, которые мне не нужны.
- Глобальная переменная аналогичным образом не работает, потому что разные запросы будут иметь одни и те же данные, чего я не хочу.
- Переменные экземпляра не работают, потому что я хочу получить доступ к данным из разных классов.
Ответы
Ответ 1
Попробуйте PerRequestCache. Я украл дизайн из SQL Query Cache.
Настройте его в config/environment.rb
с помощью
config.middleware.use PerRequestCache
затем используйте его с помощью:
PerRequestCache.fetch(:foo_cache){ some_expensive_foo }
Ответ 2
Существует также request_store gem. Из документации:
Добавьте эту строку в ваше приложение Gemfile:
gem 'request_store'
и использовать этот код для хранения и извлечения данных (ограниченных запросом):
# Set
RequestStore.store[:foo] = 0
# Get
RequestStore.store[:foo]
Ответ 3
Глобальные переменные являются злыми. Выясните, как очистить данные, которые вы хотите использовать там, где вы хотите их использовать.
Ответ 4
Один из самых популярных вариантов - использовать request_store
gem, который позволяет вам получить доступ к глобальному магазину, который вы из любой части вашего кода. Он использует Thread.current
для хранения ваших данных и позаботится об очистке данных после каждого запроса.
RequestStore[:items] = []
Помните, что, поскольку он использует Thread.current
, он не будет работать должным образом в многопоточной среде, где у вас более одного потока на запрос.
Чтобы обойти эту проблему, я реализовал хранилище, которое может использоваться совместно для потоков для одного и того же запроса. Он называется request_store_rails
, он потокобезопасен, и использование очень похоже:
RequestLocals[:items] = []
Ответ 5
Вы считали флеш? Он использует сеанс, но автоматически очищается.
Ответ 6
Memoisation?
В соответствии с этот railscast он хранится для каждого запроса.
Ответ 7
приложение/модели/my_cacher.rb
class MyCacher
def self.result
@@result ||= begin
# do expensive stuff
# and cache in @@result
end
end
end
Синтаксис || = в основном означает "сделать следующее, если @@result is nil" (т.е. еще ничего не установлен). Просто убедитесь, что последняя строка в начале/конце блока возвращает результат.
Затем в ваших представлениях/моделях/независимо от того, что вы хотели бы просто ссылаться на функцию, когда вам это нужно:
MyCacher.result
Это будет кэшировать дорогостоящее действие на время запроса.