Ruby on Rails
Кэширование
Поиск…
Кэширование русской куклы
Вы можете захотеть вложить в кешированные фрагменты внутри других кешированных фрагментов. Это называется Russian doll caching
.
Преимущество Russian doll caching
заключается в том, что при обновлении одного продукта все остальные внутренние фрагменты могут быть повторно использованы при регенерации внешнего фрагмента.
Как объяснялось в предыдущем разделе, кешированный файл истечет, если значение updated_at
изменится для записи, от которой напрямую зависит кешированный файл. Однако это не приведет к истечению срока хранения кеша, в который вложен фрагмент.
Например, сделайте следующее представление:
<% cache product do %>
<%= render product.games %>
<% end %>
Что, в свою очередь, отражает это мнение:
<% cache game do %>
<%= render game %>
<% end %>
Если какой-либо атрибут игры будет изменен, значение updated_at
будет установлено на текущее время, тем самым заканчивая кеш.
Однако, поскольку updated_at
не будет изменен для объекта продукта, этот кеш не будет истек, и ваше приложение будет обслуживать устаревшие данные. Чтобы исправить это, мы связываем модели вместе с сенсорным методом:
class Product < ApplicationRecord
has_many :games
end
class Game < ApplicationRecord
belongs_to :product, touch: true
end
Кэширование SQL
Кэширование запросов - это функция Rails
которая кэширует набор результатов, возвращаемый каждым запросом. Если Rails
снова встретит тот же запрос для этого запроса, он будет использовать кешированный результирующий набор в отличие от повторного запуска запроса к базе данных.
Например:
class ProductsController < ApplicationController
def index
# Run a find query
@products = Product.all
...
# Run the same query again
@products = Product.all
end
end
Во второй раз, когда тот же запрос выполняется с базой данных, он фактически не попадет в базу данных. В первый раз, когда результат возвращается из запроса, он сохраняется в кеше запросов (в памяти), а во второй раз он извлекается из памяти.
Однако важно отметить, что кеши запросов создаются в начале действия и уничтожаются в конце этого действия и, таким образом, сохраняются только на время действия. Если вы хотите сохранить результаты запроса более устойчивым образом, вы можете с низким уровнем кэширования.
Кэширование фрагментов
Rails.cache
, предоставляемый ActiveSupport, может использоваться для кэширования любого сериализуемого объекта Ruby через запросы.
Чтобы извлечь значение из кеша для данного ключа, используйте cache.read
:
Rails.cache.read('city')
# => nil
Используйте cache.write
для записи значения в кеш:
Rails.cache.write('city', 'Duckburgh')
Rails.cache.read('city')
# => 'Duckburgh'
В качестве альтернативы, используйте cache.fetch
для чтения значения из кеша и необязательно напишите по умолчанию, если нет значения:
Rails.cache.fetch('user') do
User.where(:is_awesome => true)
end
Возвращаемое значение переданного блока будет присвоено кешу под заданным ключом, а затем возвращено.
Вы также можете указать срок действия кеша:
Rails.cache.fetch('user', :expires_in => 30.minutes) do
User.where(:is_awesome => true)
end
Кэширование страницы
Вы можете использовать кеш страницы page_caching для кэширования отдельных страниц. Это сохраняет результат одного динамического запроса как статический HTML-файл, который служит вместо динамического запроса при последующих запросах. README содержит полные инструкции по установке. После настройки используйте caches_page
класса caches_page
в контроллере для кэширования результата действия:
class UsersController < ActionController::Base
caches_page :index
end
Используйте expire_page
для принудительного истечения срока хранения кеша, удалив сохраненный файл HTML:
class UsersController < ActionController::Base
caches_page :index
def index
@users = User.all
end
def create
expire_page :action => :index
end
end
Синтаксис expire_page
имитирует синтаксис url_for
и друзей.
HTTP-кеширование
Rails> = 3 поставляется с возможностями кэширования HTTP из коробки. Это использует заголовки Cache-Control
и ETag
чтобы контролировать, как долго клиент или посредник (например, CDN) могут кэшировать страницу.
В действии контроллера используйте expires_in
для установки длины кеширования для этого действия:
def show
@user = User.find params[:id]
expires_in 30.minutes, :public => true
end
Используйте expires_now
для принудительного немедленного истечения кэшированного ресурса для любого клиента или посредника:
def show
@users = User.find params[:id]
expires_now if params[:id] == 1
end
Кэширование действий
Подобно кэшированию страниц, кэширование действий кэширует всю страницу. Разница в том, что запрос попадает в стек Rails, поэтому перед запуском фильтров перед тем, как кеш будет обслуживаться. Он извлекается из Rails в actionpack-action_caching gem .
Общим примером является кэширование действия, требующего аутентификации:
class SecretIngredientsController < ApplicationController
before_action :authenticate_user!, only: :index, :show
caches_action :index
def index
@secret_ingredients = Recipe.find(params[:recipe_id]).secret_ingredients
end
end
Параметры включают :expires_in
, custom :cache_path
(для действий с несколькими маршрутами, которые должны кэшироваться по-разному) и :if
/ :unless
контролировать, когда действие должно быть кэшировано.
class RecipesController < ApplicationController
before_action :authenticate_user!, except: :show
caches_page :show
caches_action :archive, expires_in: 1.day
caches_action :index, unless: { request.format.json? }
end
Когда макет имеет динамический контент, кешируйте только содержимое действия, передавая layout: false
.