Кешировать только основное содержание в рельсах

Использование Rails 3.1.1 и Heroku.

Я считаю, что это должно быть довольно легко исправить, но я не могу найти (и легко проверить), как это сделать. У меня очень медленный контроллер (6 сек) Product#show, с большим количеством N+1 и другими вещами, которые мне придется решить.

Сайт представляет собой сайт с двумя столбцами (main-column а также right-column) откуда основной контент Product#show отображается в одном столбце и daily product показаны в другом, в том числе "Случайный продукт из базы данных".

То, что я хочу сделать, это чтобы содержимое main-column который создан Product#show быть кэшированным (и, таким образом, обойти контроллер и выиграть 6 секунд). Однако я хочу, чтобы правый столбец был динамическим (и загружался для каждого запроса страницы).

Если я использую caches_page :show он будет кэшировать весь сайт, включая right-column, что заставляет меня истекать кэш каждый день, чтобы иметь возможность загрузить новый Daily Product, Не очень хорошее решение

Если я использую cache('product-show' + @product.slug) do он только кэширует представление (верно?) и все равно должен пройти через контроллер.

Итак, как я могу решить это?

2 ответа

Решение

Вы можете добиться этого с помощью кэширования фрагментов, как показано ниже:

def show

  if !fragment_exist?("main_content")
    @products = Product.all
    @users_count = User.count
  end

  @random_products = Product.order("RANDOM()").limit(10)

end

show.html.erb

<!--MAIN CONTENT-->
<% cache("main_content") do %>
    <%= @users_count %>
    <% @products.each do |product| %>
        <%= product.name %>
    <% end %>
<% end %>

<!--SIDE CONTENT-->
<% @random_products.each do %>
    <%= product.name %>  
<% end %>

Используйте фрагментное кэширование и не загружайте вещи в контроллер.

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

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

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

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