Rails кэширует коллекцию с нумерацией страниц

Просто исследую лучший способ кэширования разбитой на страницы коллекции. В настоящее время использую jbuilder для вывода JSON и играю с различными параметрами cache_key.

Лучший пример, который я видел, - это использование последней записи updated_at плюс количество элементов в коллекции.

def cache_key
      pluck("COUNT(*)", "MAX(updated_at)").flatten.map(&:to_i).join("-")
end

определяется здесь: https://gist.github.com/aaronjensen/6062912

Однако это не сработает для нумерации страниц, где у меня всегда есть 10 предметов в моей коллекции.

Есть ли обходные пути для этого?

2 ответа

Решение

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

Вы можете передать множество вещей в метод кеша для генерации ключа. Если у вас всегда есть 10 элементов на странице, я не думаю, что количество очень ценно. Тем не менее, номер страницы и последний обновленный элемент будет.

cache ["v1/items_list/page-#{params[:page]}", @items.maximum('updated_at')] do

будет генерировать ключ кеша, как

v1/items_list/page-3/20140124164356774568000

При кэшировании русской куклы вы также должны кэшировать каждый элемент в списке

# index.html.erb
<%= cache ["v1/items_list/page-#{params[:page]}", @items.maximum('updated_at')] do %>
  <!-- v1/items_list/page-3/20140124164356774568000 -->
  <%= render @items %>
<% end %>

# _item.html.erb
<%= cache ['v1', item] do %>
  <!-- v1/items/15-20140124164356774568000 -->
  <!-- render item -->
<% end %>

Кэширование нумерации страниц сложно. Обычный трюк использования количества коллекции и макс updated_at в основном не применяется!

Как вы сказали, количество коллекций является таким бесполезным, если только вы не разрешите динамическое per_page ценности.

Последний updated_at полностью зависит от сортировки вашей коллекции.

Представьте, что новая запись добавлена ​​и заканчивается на первой странице. Это означает, что одна запись, ранее страница 1, теперь попадает на страницу 2. Одна предыдущая запись страницы 2 теперь становится страницей 3. Если новая запись страницы 2 не обновляется позднее, чем предыдущий максимум, ключ кэша остается тем же, но коллекция не является! То же самое происходит, когда запись удаляется.

Только если вы можете гарантировать, что новые записи всегда будут на последней странице, и никакие записи не будут удалены, используя максимальное updated_at это твердый путь.

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

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

Если вы используете postgres в качестве базы данных, этот гем может вам помочь, хотя я никогда не использовал его сам. https://github.com/cmer/scope_cache_key

И рельсы 4 вилки: https://github.com/joshblour/scope_cache_key

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