Кэширование фрагментов Rails коллекции

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

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

_order_list.html.erb

<% cache(@orders) do %>
    <%= render @orders %>
  <% end %>

_order.html.erb

<% cache(order) do %>
  ...view code for order here
<% end %>

Однако я не уверен насчет кэширования коллекции (@orders). Будет ли тогда всем пользователям обслуживаться один и тот же набор кэшированных @orders (что нежелательно)?

Другими словами, как я могу обеспечить кэширование всей коллекции @orders для каждого пользователя в отдельности?

1 ответ

Решение

Будет ли тогда всем пользователям обслуживаться один и тот же набор кэшированных @orders (что нежелательно)?

На самом деле cache_digests не кешируется @orders самих себя. Кеширует html часть страницы для конкретного заданного объекта или набора объектов (например, @orders). Каждый раз, когда пользователь запрашивает веб-страницу, @orders переменная будет установлена ​​в действии контроллера и его digest сравнивается с кэшированным дайджестом.

Итак, если мы получим @orders как это:

def index
  @orders = Order.where(:id => [1,20,34]).all
end

То, что мы собираемся получить, это кэшированный вид с такой меткой:

views / orders /1-20131202075718784548000 / orders /20-20131220073309890261000 / orders /34-20131223112753448151000 / 6da080fdcd3e2af29fab811488a953d0

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

Но вот некоторые недостатки вашего подхода:

  1. Кэши страниц всегда хранятся на диске. Это означает, что вы не можете иметь штамп страницы любой желаемой длины. Как только вы извлекаете солидную кучу заказов за один раз, вы превышаете лимит вашей операционной системы для имен файлов (например, это 255 байт для linux) и в итоге получаете ошибку времени выполнения.
  2. Заказы - это динамический контент. Как только хотя бы одно из них обновляется, ваш кэш становится недействительным. Генерация кэша и сохранение его на диск - довольно трудоемкая операция, поэтому было бы лучше кэшировать каждый заказ отдельно. В этом случае вам придется заново генерировать кэш для одного заказа, а не заново создавать кэш всей массивной коллекции.
Другие вопросы по тегам