Spec-Zone.ru › Ruby on Rails 5.0

модуль ActionView::Helpers::CacheHelper

Общедоступные методы экземпляра

cache(name = {}, options = {}) { || ... } Показать исходный код
# File actionview/lib/action_view/helpers/cache_helper.rb, line 152
def cache(name = {}, options = {}, &block)
  if controller.respond_to?(:perform_caching) && controller.perform_caching
    name_options = options.slice(:skip_digest, :virtual_path)
    safe_concat(fragment_for(cache_fragment_name(name, name_options), options, &block))
  else
    yield
  end

  nil
end

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

Лучший способ использования - это кэширование с истечением срока действия на основе ключа, например, на хранилище кэша, как Memcached, которое автоматически удалит старые записи. Подробнее о кэшировании с истечением срока действия на основе ключа см.: signalvnoise.com/posts/3113-how-key-based-cache-expiration-works

При использовании этого метода укажите зависимость кэша как имя кэша, например:

<% cache project do %>
  <b>All the topics on this project</b>
  <%= render project.topics %>
<% end %>

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

views/projects/123-20120806214154/7a1156131a6928cb0026877f8b749ac9
      ^class   ^id ^updated_at    ^template tree digest

Таким образом, кэш автоматически обновляется всякий раз, когда обновляется `updated_at` проекта.

Если ваш кэш шаблона зависит от нескольких источников (старайтесь избегать этого, чтобы упростить задачу), вы можете указать все эти зависимости как часть массива:

<% cache [ project, current_user ] do %>
  <b>All the topics on this project</b>
  <%= render project.topics %>
<% end %>

Это включит оба объекта в ключ кэша, и обновление любого из них приведет к истечению срока действия кэша.

Хеш шаблона

Хеш шаблона, добавляемый в ключ кэша, вычисляется путём взятия md5 от всего содержимого файла шаблона. Это гарантирует, что ваши кэши будут автоматически истекать при изменении файла шаблона.

Обратите внимание, что md5 вычисляется для всего файла шаблона, а не только для содержимого внутри вызова блока do/end. Поэтому возможно, что изменение чего-либо вне этого вызова всё равно приведёт к истечению срока действия кэша.

Кроме того, модуль автоматического определения хешей будет просматривать ваш файл шаблона на предмет явных и неявных зависимостей и включать их в хеш.

Модуль определения хеша можно пропустить, передав `skip_digest: true` в качестве параметра вызову `cache`:

<% cache project, skip_digest: true do %>
  <b>All the topics on this project</b>
  <%= render project.topics %>
<% end %>

Неявные зависимости

Большинство зависимостей шаблонов могут быть получены из вызовов `render` в самом шаблоне. Вот несколько примеров вызовов `render`, которые Cache Digest умеет распознавать:

render partial: "comments/comment", collection: commentable.comments
render "comments/comments"
render 'comments/comments'
render('comments/comments')

render "header" => render("comments/header")

render(@topic)         => render("topics/topic")
render(topics)         => render("topics/topic")
render(message.topics) => render("topics/topic")

Однако не все вызовы `render` можно получить таким образом. Вот несколько примеров того, что невозможно получить:

render group_of_attachments
render @project.documents.where(published: true).order('created_at')

Вам придётся переписать их в явном виде:

render partial: 'attachments/attachment', collection: group_of_attachments
render partial: 'documents/document', collection: @project.documents.where(published: true).order('created_at')

Явные зависимости

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

<%= render_sortable_todolists @project.todolists %>

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

<%# Template Dependency: todolists/todolist %>
<%= render_sortable_todolists @project.todolists %>

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

<%# Template Dependency: events/* %>
<%= render_categorizable_events @person.events %>

Это помечает каждый шаблон в каталоге как зависимость. Чтобы найти эти шаблоны, путь с подстановочным знаком должен быть определён абсолютно от `app/views` или путей, добавленных с помощью prepend_view_path или append_view_path. Таким образом, подстановочный знак для `app/views/recordings/events` будет `recordings/events/*` и т.д.

Шаблон для соответствия явным зависимостям — /# Template Dependency: (\S+)/, поэтому важно вводить его точно. Вы можете объявлять только одну зависимость шаблона в строке.

Внешние зависимости

Если вы используете метод хелпера, например, внутри кэшированного блока, и затем обновляете этот хелпер, вам также нужно будет обновить кэш. В этом нет особой разницы, но md5 файла шаблона должен измениться. Одно из рекомендаций — просто быть явным в комментарии, например:

<%# Helper Dependency Updated: May 6, 2012 at 6pm %>
<%= some_helper_method(person) %>

Теперь всё, что вам нужно сделать, это изменить эту метку времени при изменении метода хелпера.

Кэширование коллекций

При отрисовке коллекции объектов, каждый из которых использует один и тот же фрагмент, можно передать параметр `cached`. Для коллекций, отрисованных так:

<%= render partial: 'notifications/notification', collection: @notifications, cached: true %>

`cached: true` заставит Action View одновременно читать несколько шаблонов из кэша вместо вызова каждого шаблона по отдельности.

Шаблоны в коллекции, которые ещё не кэшированы, записываются в кэш.

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

# notifications/_notification.html.erb
<% cache notification do %>
  <%# ... %>
<% end %>

Любой рендеринг коллекции найдёт эти кэшированные шаблоны при попытке одновременного чтения нескольких шаблонов.

cache_fragment_name(name = {}, skip_digest: nil, virtual_path: nil) Показать исходный код
# File actionview/lib/action_view/helpers/cache_helper.rb, line 197
def cache_fragment_name(name = {}, skip_digest: nil, virtual_path: nil)
  if skip_digest
    name
  else
    fragment_name_with_digest(name, virtual_path)
  end
end

Этот помощник возвращает имя ключа кэша для заданного вызова кэширования фрагмента. Передавая skip_digest: значение `true` в параметр `cache`, можно вручную пропустить вычисление хеша фрагментов кэша. Это полезно, когда фрагменты кэша нельзя вручную обновить, если вам не известен точный ключ, например, при использовании memcached.

Хеш будет сгенерирован с использованием virtual_path: , если он предоставлен.

cache_if(condition, name = {}, options = {}) { || ... } Показать исходный код
# File actionview/lib/action_view/helpers/cache_helper.rb, line 169
def cache_if(condition, name = {}, options = {}, &block)
  if condition
    cache(name, options, &block)
  else
    yield
  end

  nil
end

Кэшировать фрагменты представления, если condition равно `true`

<% cache_if admin?, project do %>
  <b>All the topics on this project</b>
  <%= render project.topics %>
<% end %>
cache_unless(condition, name = {}, options = {}, &block) Показать исходный код
# File actionview/lib/action_view/helpers/cache_helper.rb, line 185
def cache_unless(condition, name = {}, options = {}, &block)
  cache_if !condition, name, options, &block
end

Кэшировать фрагменты представления, если condition не равно `true`

<% cache_unless admin?, project do %>
  <b>All the topics on this project</b>
  <%= render project.topics %>
<% end %>

© 2004–2018 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API