Rails Action Caching для пользовательских записей
Я новичок в рельсах, пытаюсь реализовать кэширование для моего приложения. Я установил memcached и настроил его в своем development.rb следующим образом:
config.action_controller.perform_caching = true
config.cache_store = :mem_cache_store
У меня есть контроллер ProductsController, который показывает конкретные продукты пользователя, когда они вошли в систему.
class ProductsController < ApplicationController
caches_action :index, :layout => false
before_filter :require_user
def index
@user.products
end
end
The route for index action is: /products
Проблема в том, что когда я вхожу как
1) Пользователь A впервые, rails попадает в мой контроллер и кеширует действие продуктов.
2) Я выхожу из системы и захожу как пользователь B, он по-прежнему регистрируется как пользователь A и показывает продукты для пользователя A, а не пользователя B. Он даже не попал в мой контроллер.
Ключом, вероятно, является маршрут, в моей memcached консоли я вижу, что он выбирается на основе того же ключа.
20 get views/localhost:3000/products
20 sending key views/localhost:3000/products
Разве кэширование действий не то, что я должен использовать? Как бы я кешировал и отображал пользовательские продукты?
Спасибо за вашу помощь.
2 ответа
Первая проблема заключается в том, что ваш before_filter для require_user находится после кэширования действий, поэтому он не запустится. Чтобы исправить это, используйте этот код контроллера:
class ProductsController < ApplicationController
before_filter :require_user
caches_action :index, :layout => false
def index
@products = @user.products
end
end
Во-вторых, для кэширования действий вы делаете то же самое, что и кэширование страниц, но после запуска фильтров ваш код @user.products не будет работать. Есть несколько способов исправить это.
Во-первых, если вы хотите, вы можете кэшировать действие на основе параметров, которые передаются на страницу. Например, если вы передаете параметр user_id, вы можете кэшировать на основе этого параметра, например так:
caches_action :index, :layout => false, :cache_path => Proc.new { |c| c.params[:user_id] }
Во-вторых, если вы хотите просто кэшировать запрос, а не всю страницу, вы должны полностью удалить кэширование действий и только кэшировать запрос, например так:
def index
@products = Rails.cache.fetch("products/#{@user.id}"){ @user.products }
end
Это должно помочь вам получить отдельный кеш для каждого пользователя.
Основываясь на ответе Пана Томакоса, если вы наследуете от контроллера, который обрабатывает аутентификацию, вам нужно скопировать before_filter из родительского класса. Например:
class ApplicationController < ActionController::Base
before_filter :authenticate
end
class ProductsController < ApplicationController
# must be here despite inheriting from ApplicationController
before_filter :authenticate
caches_action :index, :layout => false
end