Rails Action Caching для пользовательских записей - PullRequest
6 голосов
/ 23 февраля 2011

Я новичок в рельсах, пытаюсь реализовать кэширование для моего приложения. Я установил 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 ]

15 голосов
/ 24 февраля 2011

Первая проблема заключается в том, что ваш 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

Это должно помочь вам получить отдельный кеш для каждого пользователя.

0 голосов
/ 11 апреля 2011

Основываясь на ответе Пана Томакоса, если вы наследуете от контроллера, который обрабатывает аутентификацию, вам нужно скопировать 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
...