модуль ActionView::Helpers::CacheHelper
Открытые методы экземпляра
Этот помощник предоставляет метод для кэширования фрагментов представления, а не всего действия или страницы. Этот метод полезен для кэширования таких фрагментов, как меню, списки новых тем, статических фрагментов HTML и т. д. Этот метод принимает блок, содержащий содержимое, которое вы хотите кэшировать.
Лучший способ использования — это кэширование с истечением срока действия на основе ключа с помощью хранилища кэша, такого как Memcached, которое автоматически удаляет старые записи. Подробнее о кэшировании с истечением срока действия на основе ключа см.: 37signals.com/svn/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 вычисляется для всего файла шаблона, а не только для того, что находится внутри вызова cache 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 Digests умеет декодировать:
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 %>
Используемый шаблон для сопоставления — /# Шаблон Зависимость: ([^ ]+)/, поэтому важно набирать его именно так. Вы можете указать только одну зависимость шаблона в строке.
Внешние зависимости
Если вы используете метод хелпера, например, внутри кэшированного блока, и затем обновляете этот хелпер, вам также необходимо обновить кэш. Это не имеет значения, как вы это сделаете, но md5 файла шаблона должен измениться. Одним из рекомендаций является явное указание, как в комментарии, например:
<%# Helper Dependency Updated: May 6, 2012 at 6pm %> <%= some_helper_method(person) %>
Теперь всё, что вам нужно сделать, это изменить эту метку времени при изменении метода хелпера.
# File actionview/lib/action_view/helpers/cache_helper.rb, line 113
def cache(name = {}, options = nil, &block)
if controller.respond_to?(:perform_caching) && controller.perform_caching
safe_concat(fragment_for(cache_fragment_name(name, options), options, &block))
else
yield
end
nil
end Этот помощник возвращает имя ключа кэша для данного вызова кэширования фрагмента. Передавая skip_digest: true в cache, можно вручную пропустить вычисление хэша фрагментов кэша. Это полезно, когда фрагменты кэша нельзя вручную обновить, если вы не знаете точного ключа, что имеет место при использовании memcached.
# File actionview/lib/action_view/helpers/cache_helper.rb, line 154
def cache_fragment_name(name = {}, options = nil)
skip_digest = options && options[:skip_digest]
if skip_digest
name
else
fragment_name_with_digest(name)
end
end Кэширует фрагменты представления, если condition истинно
<%= cache_if admin?, project do %> <b>All the topics on this project</b> <%= render project.topics %> <% end %>
# File actionview/lib/action_view/helpers/cache_helper.rb, line 129
def cache_if(condition, name = {}, options = nil, &block)
if condition
cache(name, options, &block)
else
yield
end
nil
end Кэширует фрагменты представления, если condition ложно
<%= cache_unless admin?, project do %> <b>All the topics on this project</b> <%= render project.topics %> <% end %>
# File actionview/lib/action_view/helpers/cache_helper.rb, line 145
def cache_unless(condition, name = {}, options = nil, &block)
cache_if !condition, name, options, &block
end
© 2004–2016 David Heinemeier Hansson
Licensed under the MIT License.