Кеширование страниц средствами Ruby on Rails 25 февраля 10
Я тут занялся оптимизированием RentFeed, где большую часть страниц можно положить в кеш и обновлять несколько раз в день. Самый тупой и быстрый кеш в виде статических файлов, отдаваемых непосредственно апачем.
Рельсы умеют такое делать «из коробки», практически одной строчкой:
class SomeController < ApplicationController caches_page :index def index end end
Все! Кеш уже работает. Правда, почему-то рельсы не предусматривают две вещи. Кеш не работает с GET-параметрами – раз. Хранится прямо в public – два.
GET-параметры
Тут все просто: хочешь, чтобы для разного набора параметров кешировались разные страницы – помещай параметры в путь. Кстати, к таким ссылкам и Google лучше относится.
Для меня это в первую очередь касалось постраничной разбивки. Если ты используешь will_paginate, то тебе достаточно вынести URL с номером страницы в таблицу роутов:
map.resources :items map.paged_items '/items/page/:page', :controller => 'items', :action => 'index'
Перемещаем кеш в более удобное место (например, в public/cache)
Путь к кешу указывается в конфиге:
# config/environments/production.rb config.action_controller.page_cache_directory = RAILS_ROOT+"/public/cache/"
Осталось научить Apache забирать кеш из нужного каталога. Решается это довольно простыми реврайтами, не считая того, что отдавать нужно только файлы, которые точно лежат в кеше – иначе Rails станет получать неправильные пути и перестанет работать.
В общем, нужен вот такой .htaccess:
# public/.htaccess
RewriteEngine On
# убираем слеш в конце пути
RewriteCond %{REQUEST_URI} ^([^.]+)/$
RewriteRule ^[^.]+/$ /%1 [QSA,L]
# перенаправляем в кеш, только если там есть файл
RewriteCond %{THE_REQUEST} ^(GET|HEAD)
RewriteCond %{DOCUMENT_ROOT}/cache/%1 -f
RewriteRule ^.+$ /cache/%1 [QSA,L]
# то же для страниц без расширения (к ним Rails приписывает .html)
RewriteCond %{THE_REQUEST} ^(GET|HEAD)
RewriteCond %{REQUEST_URI} ^([^.]+)$
RewriteCond %{DOCUMENT_ROOT}/cache/%1.html -f
RewriteRule ^[^.]+$ /cache/%1.html [QSA,L]
# то же для пустого пути
RewriteCond %{THE_REQUEST} ^(GET|HEAD)
RewriteCond %{DOCUMENT_ROOT}/cache/index.html -f
RewriteRule ^$ /cache/index.html [QSA,L]Теперь можно очищать весь кеш вместе обыкновенным rm -rf public/cache/*.

Подписаться на RSS

Комментарии
Спасибо за материал. Как раз то, что искал.
[...] раз я занимался кешированием страниц на сайте без аутентификации. Что даже более важно – сайт этот для всех выглядит [...]
# убираем слеш в конце пути
RewriteCond %{REQUEST_URI} ^([^.]+)/$
RewriteRule ^[^.]+/$ /%1 [QSA,L]
У меня на сайте не работает((( я уже все перепробовал… в чем может быть дело????