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

Вы считали флеш? Он использует сеанс, но автоматически очищается.

Ответ 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

Это будет кэшировать дорогостоящее действие на время запроса.