Рельсы 4 фрагмента кеширования для разных просмотров

В моем приложении rails 4 я пытаюсь избавиться от кеширования, но я немного сбит с толку из-за различных версий настроек ключа кеша, помощников кеша и автоматического истечения срока действия.

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

1: последние пользователи в боковой панели

Я хотел бы показать последние пользователи. Это, конечно, одинаково для всех пользователей в приложении и отображается на всех страницах. В Railscasts я видел похожий пример, когда он истек, позвонив expire_fragment... в контроллере. Но согласно другим ресурсам, это должно истечь автоматически, когда что-то меняется (например, регистрация нового пользователя). Итак, мой вопрос: правильно ли я устанавливаю ключ и будет ли он автоматически истек?

_sidebar.html.erb (отображается на всех страницах боковой панели)

<% cache 'latest-users' %>
  <%= render 'users/user_sidebar' %>
<% end %>

_users_sidebar.html.erb

<% @profiles_sidebar.each do |profile| %>
  <%= profile.full_name %>
  ........
<% end %>

2: страница выставки продукта

Я хотел бы отобразить данный продукт (только на странице шоу). Это то же самое снова для всех пользователей, но есть больше версий, так как есть больше продуктов. Вопрос опять тот же: правильно ли я настраиваю ключ, и не истечет ли он автоматически?

Продукты / show.html.erb

<% cache @product %>
  <%= @product.name.upcase %>
  <%= @product.user.full_name %>
<% end %>

3: продукты / индекс (разбито на страницы с волевой страницей)

Здесь я хотел бы кэшировать все продукты на заданной странице нумерации страниц, чтобы продукты кэшировались блоками. Это также одинаково для всех пользователей, и отображается только на products index page, (Позже я хотел бы реализовать russian-doll-caching для отдельных продуктов на этой странице.) Мой вопрос: правильно ли я это делаю, и срок его действия истечет?

продукты index.html.erb

<% cache [@products, params[:page]] %>
  <%= render @products %>
<% end %>

_product.html.erb

<%= product.name %>
<%= product.user.full_name %>
.....

Пример кода, который я пытался использовать (не уверен, что он хороший):

Сначала с индексной страницей и без русской куклы.

введите описание изображения здесь

Второй - с русской куклой для шоу-страницы с комментариями.

введите описание изображения здесь

2 ответа

Решение

Существует довольно большая разница между кэшированием одной записи и коллекцией записей.

Вы можете просто сказать, была ли изменена одна запись, посмотрев на метку времени. Метод cache_key по умолчанию работает следующим образом:

Product.new.cache_key     # => "products/new" - never expires
Product.find(5).cache_key # => "products/5" (updated_at not available)
Person.find(5).cache_key  # => "people/5-20071224150000" (updated_at available)

Однако информация о том, когда коллекция устарела, во многом зависит от того, как она используется.

В вашем первом примере вы действительно заботитесь только о created_at отметка времени - в других ситуациях вы можете захотеть посмотреть, когда записи обновляются или даже когда связанные записи были вставлены / обновлены. Здесь нет правильного ответа.

1.

Сначала вы бы потянули N количество пользователей, упорядоченных по created_at:

@noobs = User.order(created_at: :desc).limit(10)

Мы можем просто аннулировать кеш здесь, посмотрев на первого пользователя в коллекции.

<!-- _sidebar.html.erb -->
<% cache(@noobs.first) do %>
  <%= render partial: 'users/profile', collection: @noobs %>
<% end %>

Мы можем сделать это, так как знаем, что, если новый пользователь зарегистрирован (а), он ударит предыдущий номер один в слот.

Затем мы можем кешировать каждого отдельного пользователя с помощью русской куклы. Обратите внимание, что поскольку частичное называется profile частичное передается локальной переменной profile:

<!-- users/_profile.html.erb -->
<% cache(profile) do %>
  <%= profile.full_name %>
<% end %>

2.

Да. Это истечет. Вы могли бы хотеть частичное с русским кешированием куклы как другие примеры.

3.

Для разбитой на страницы коллекции вы можете использовать идентификаторы записей в массиве для создания ключа кэша.

Ред.

Поскольку вы не хотите показывать устаревшее представление продукта, который может быть обновлен, вы также захотите использовать updated_at как ключ кеша во "внешнем слое" русской куклы.

В этом случае имеет смысл загружать записи целиком. Вы можете игнорировать мой предыдущий комментарий о .ids,

Продукты /index.html.erb:

<% cache([@products.map(&:id), @products.map(&:updated_at).max]) do %>
  <%= render @products %>
<% end %>

Продукты /_product.html.erb:

<% cache(product) do %>
  <%= product.name %>
<% end %>

ИМХО, ключ кеша - это дух всей концепции.

Теперь давайте обсудим эти примеры.

  1. последние пользователи в боковой панели: исправлена ​​строка в качестве ключа кеша

cache_key может быть views/latest-users/7a1156131a6928cb0026877f8b749ac9 который дайджест 7a11561.. является MD5 литерала блока кеша.

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

<% cache 'latest-users' do %>
  <%= render 'users/user_sidebar' %>
<% end %>
  1. страница показа продукта: объект как ключ кеша

cache_key может быть views/product/123-20160330214154/9be3eace37fa886b0816f107b581ed67обратите внимание, что кеш это пространство имен с #{product.to_s}/#{product.id}-#{product.updated_at},

В этом случае срок действия кэша истекает, когда (1) product.updated_at изменен или (2) литерал блока кэша изменен.

И обратите внимание, что кэш отличается от другого продукта id,

<% cache @product %>
  <%= @product.name.upcase %>
  <%= @product.user.full_name %>
<% end %>
  1. products/index (разбит на страницы с помощью will-paginate gem): массив в качестве ключа кэша

cache_key может быть views/product/123-20160330214154/product/456-20160330214154/d5f56b3fdb0dbaf184cc7ff72208195e не уверен в этом. но в любом случае, это должно быть расширено примерно так.

В этом случае срок действия кэша истекает, когда (1) изменяется либо product-123, либо product-456 (product.updated_at изменено) или (2) изменен литерал блока кэша.

И кеш отличается от разного контента @products по их idsтак что нет необходимости добавлять params[:page], он будет кэшировать каждую страницу из-за их различных @products содержание.

<% cache [@products, params[:page]] %>
  <%= render @products %>
<% end %>

Вы можете прочитать статью, написанную DHH, в которой очень хорошо описывается кэширование русской куклы. И API документ

Другие вопросы по тегам