Проблема с кэшированием страниц Rails и автоматическими расширениями - PullRequest
6 голосов
/ 14 мая 2011

У меня есть API на основе JSON и XML, который необходимо кэшировать на странице.Я настроил свои маршруты на API, чтобы включить формат как часть URL, так что URL похож на эту работу:

http://example.com/foo/1/bar/2/xml
http://example.com/foo/1/bar/2/json

Проблема, которую я вижу, состоит в том, что в папке public сервера,файлы сохраняются как xml.xml и json.json, и это приводит к отсутствию кэша при следующем обращении к URL.

Есть ли способ:

  1. Отключитьавтоматическое создание расширений, чтобы они вообще сохранялись без расширения?(EX: RAILS_ROOT/public/foo/1/bar/2/json)
  2. Принудительно установить для всех добавочных номеров значение .html для каждого вызова.(EX: RAILS_ROOT/public/foo/1/bar/2/json.html)

Любое из этих действий приведет к тому, что мой сервер вернет кэшированный файл вместо промаха.Как я могу это сделать?

РЕДАКТИРОВАТЬ:
Кто-то спросил соответствующий маршрут:

scope '(foo/:foo_id)', :foo_id => /\d+/ do
  get '/bar/:bar_id/:format' => 'bars#show', :bar_id => /\d+/, :format => /json|xml|html/
end

РЕШЕНИЕ :В то время как я искал официальный способ сделать это, используя встроенную поддержку кэширования страниц, я закончил тем, что использовал только фильтр после и мой собственный метод кэширования страниц, как предложил Антон

# application_controller.rb
def cache_api_page
  if REDACTEDServer::Application.config.action_controller.perform_caching
    self.class.cache_page(response.body, request.path, '')
    puts "CACHED PATH: #{request.path}"
  end
end

# bar_controller.rb
 after_filter :cache_api_page, :only => [ :show, :index ]

Ответы [ 2 ]

3 голосов
/ 17 мая 2011

Вы можете сделать это так:

class FooController < ApplicationController

  after_filter(:only => :show, :if => Proc.new { |c| c.request.format.json? }) do |controller|
    controller.class.cache_page(controller.response.body, controller.request.path, '.html')
  end

end

При обращении к http://example.com/foo/1/bar/2/json он записывает страницу в кэш (RAILS_ROOT / public / foo / 1 / bar / 2 / json.html)

И если вы снова получите http://example.com/foo/1/bar/2/json, вы получите RAILS_ROOT / public / foo / 1 / bar / 2 / json.html, но ваш http-сервер (Apache?) Должен знать о типе содержимого этих файлов.

В противном случае тип содержимого будет установлен на «text / html»

UPDATE

Вам .htaccess

<FilesMatch "\/json$">
<IfModule mod_headers.c>
  Header set Content-Type "text/json"
</IfModule>
</FilesMatch>


<FilesMatch "\/xml$">
<IfModule mod_headers.c>
  Header set Content-Type "text/xml"
</IfModule>
</FilesMatch>
0 голосов
/ 22 мая 2011

В вашем блоке конфигурации application.rb попробуйте добавить:

config.action_controller.page_cache_extension = '.html'

Следует игнорировать расширение, рассчитанное по запросу, и всегда использовать его. Вы также можете попробовать использовать это с пустой строкой.

РЕДАКТИРОВАТЬ: на самом деле это не будет работать, потому что это только устанавливает по умолчанию. Если запрос имеет расширение (в вашем случае, заключенное из: format), он будет использован.

Я предлагаю изменить: отформатируйте в ваших маршрутах что-то еще, чтобы рельсы не придавали особого значения, например: fmt. Тогда rails не должен добавлять расширение и значение по умолчанию '.html'.

РЕДАКТИРОВАТЬ2: Если вам нужно использовать: формат вы можете monkeypatch Rails:

ActionController::Caching::Pages::ClassMethods
  private
  def page_cache_file(path)
    name = (path.empty? || path == "/") ? "/index" : URI.unescape(path.chomp('/'))
    name << page_cache_extension #unless (name.split('/').last || name).include? '.'
    return name
  end
end

Обратите внимание на знак комментария, который я добавил перед словом «если». Это часть, которая переопределяет значение по умолчанию из моего первого ответа.

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