<%= link_to "your profile", :controller => 'profiles', :action => 'show' %>
<%= link_to "logout" , :controller => "members", :action => "logout" %>
Вероятно, вы обратили внимание на ссылку my profile. Изначально эта ссылка указывала на профиль пользователя, однако это помешает кэшированию нашей домашней страницы. Вместо этого я просто направил ссылку на действие index, без указания ID пользователя. А затем действие index перенаправляет пользователя на корректную страницу профиля:
Листинг 2. Перенаправление пользователя на корректную страницу профиля
def index
redirect_to my_profile_url
end
В листинге 2 метод my_profile_url определяет URL соответствующего профиля на основе типа пользователя, который может быть “знаменитостью”, “советником” или “рядовым участником”. У каждого есть отдельная страница профиля. На данном этапе приложение полностью работоспособно, однако вы увидите все четыре ссылки: по две ссылки для вошедших в систему (logged_in) и не вошедших (logged_out):
login
register
your profile
logout
Следующий шаг заключается в создании cookie-файла, в котором будет храниться текущий тип пользователя. Для ChangingThePresent cookie-файл создается во время входа в систему и хранит текущий ID входа в систему. Cookie-файл будет удален в момент выхода из системы:
Листинг 3. Создание и удаление cookie-файлов при входе и выходе из системы
def login
if request.post?
self.current_user = User.authenticate(params['user_login'], params['user_password'])
...
if logged_in?
set_cookies
...
end
end
def logout
end
private
def set_cookies
cookies[:login] = current_user.login
cookies[:image] = find_thumb(current_user.member_image)
end
def logout
cookies.delete :login
cookies.delete :image
...
end
В листинге 3 logged_in? - это частный метод, который возвращает значение true ("истина"), если пользователь вошел в систему. Описанные выше методы Rails создают три cookie-файла при входе пользователя в систему и удаляют их при выходе. Не беспокойтесь за данные. Пока что они не нужны. Главное, что теперь можно определить, зашел ли пользователь в систему, не обращаясь к среде Rails. Теперь необходимо убедиться, что прекращение срока действия cookie-файла соответствует политике прекращения срока действия сайта. В нашем случае так и есть. Следовательно, все готово для кэширования страниц.
На следующем этапе мы будем выборочно скрывать и отображать соответствующие записи на основе cookie-файлов пользователя. Я добавил следующий код JavaScript в public/javascripts/application.js:
Листинг 4. Код JavaScript для отображения и скрытия данных о входе в систему
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
function handle_cached_user() {
var login_cookie = readCookie('login');
var logged_in = document.getElementById('logged_in');
var logged_out = document.getElementById('logged_out');
if(login_cookie == null) {
logged_in.style.display = 'none';
logged_out.style.display = 'block';
} else {
logged_out.style.display = 'none';
logged_in.style.display = 'block';
}
}
Первая функция считывает значение cookie-файла из JavaScript, а вторая работает с DOM. Данный код можно упростить, если использовать библиотеку прототипов Prototype, однако я включил в него основные функции для поиска в DOM , чтобы код был понятен всем читателям. Последний этап заключается в вызове функции JavaScript при загрузке страницы. В программу необходимо добавить следующее:
Листинг 5. Вызов функций JavaScript при загрузке страницы
Это простой код JavaScript. Функция handle_cached_user загружается при загрузке страницы, и отображает или скрывает необходимые элементы. Теперь можно включить кэширование страницы, добавив следующий элемент кода в контроллер:
caches_page :index
Все работает идеально. Однако по-прежнему необходимо периодически удалять первую страницу из кэша, если необходимо сделать так, чтобы срок актуальности страницы истек. Для реализации данной задачи я просто время от времени удаляю public/index.html. Метод "спрятать и найти" отлично работает для тех страниц, у которых есть несколько классификаций пользователей, но не будет работать для отображения данных каждого отдельного пользователя, как показано на рисунке 2. В этом случае, придется использовать сочетание методов "спрятать и найти" и "показать и добавить".
Реализация метода "показать и добавить"
Взгляните на рисунок 2 еще раз. Методика "спрятать и найти" будет использоваться для выбора правильного варианта фрагмента в зависимости от того, вошел ли пользователь в систему или нет, а затем будет применяться технология "показать и добавить" для заполнения динамических фрагментов страницы на основе содержимого cookie-файлов, создание которых описано в листинге 3, строки четыре и пять. Подчеркиваю, что при использовании технологии "показать и добавить" я изменяю элементы страницы так, чтобы они соответствовали каждому отдельно взятому пользователю.
Во-первых, у нас имеется статический контент, который отображает каждую составляющую: одна для пользователя, который не выполнил вход в систему, другая - для вошедшего в систему пользователя. По умолчанию предполагается, что пользователь не вошел в систему, поэтому раздел logged_in скрыт при помощи стилевого форматирования display: none. Впоследствии при необходимости их можно скрывать или показывать при помощи кода JavaScript. Обратите внимание, что для определения каждого раздела используются те же самые имена logged_in и logged_out, поэтому вносить какие-либо изменения в JavaScript, написанный для домашней страницы, не придется:
Листинг 6. Отображение фрагментов и для вошедших, и для не вошедших в систему пользователей
<%= link_to %(
Hi, ) +
%(
) + "my_login" +
%(), {:controller => 'profiles', :action => 'show', :id => 'my_login'},
{:id => 'profile_link'} %>
Not my_login?
<%= image_button "logout", :controller => "members", :action => "logout" %>
Если вы хорошо знаете Rails, то вероятно обратили внимание на несколько пользовательских функций помощи. Можно увидеть 4 различных элемента динамического контента, которые необходимо заменять при каждой загрузке страницы с помощью JavaScript: информация о входе в систему (в трех местах) и изображение участника (в одном месте). Код JavaScript состоит из изменений функции handle_cached_user и нового метода для управления обновлением страницы для динамического пользователя. При написании данной статьи код был слегка упрощен. Добавьте в файл application.js следующую функцию:
Листинг 8. Замена элементов пользовательской составляющей
function handle_user_partial() {
var login_cookie = readCookie('login');
var image_cookie = readCookie('image');
var profileLink = document.getElementById('profile_link');
profileLink.href = '/member/' + login_cookie;
document.getElementById('bold_link').firstChild.nodeValue=login_cookie;
document.getElementById('not_mine').firstChild.nodeValue="Not " + login_cookie + "?";
document.getElementById('link_for_member_thumbnail').href="/member/" + login_cookie;
document.getElementById('member_thumbnail').src=image_cookie.replace(/%2[Ff]/g,"/");
document.getElementById('member_thumbnail').alt=login_cookie;
}
В листинге 8 функция JavaScript сначала считывает cookie-файлы и получает один элемент дерева DOM: ссылку на профиль текущего пользователя, которая называется profile_link. Затем функция handle_user_partial:
заменяет имя вошедшего в систему пользователя (которое хранится в login_cookie) на my_login для создания правильного URL страницы профиля пользователя.
добавляет имя вошедшего в систему пользователя в DOM-элемент, который содержит текст, написанный жирным шрифтом и обозначающий вошедшего в систему пользователя.
добавляет простое предложение "Not login?" в DOM-элемент, содержащий подпись logout в разделе login.
находит DOM-элемент, в котором хранится изображение участника и заменяет URL универсального изображения на URL изображения конкретного участника, который хранится в image_cookie.
а также заменяет тег alt для изображения на имя пользователя (login), на тот случай, если рисунок не будет отображен.
При перемещении по DOM вы обнаружите, что возникают такие ситуации, когда необходимо перейти непосредственно к некоторому DOM-элементу, а иногда необходим конкретный потомок этого элемента, например, когда вы работаете с текстом. Для поиска первого потомка заданного DOM-элемента, я использовал функцию firstChild. Библиотека Prototype благодаря более простому синтаксису слегка упрощает работу с конкретными DOM-элементами, однако это выходит за рамки данной статьи.
Так как все cookie-файлы уже созданы, последним шагом является вызов JavaScript из существующей функции handle_cached_user. Напоминаю, что эта функция располагается в public/javascripts/application.js:
Листинг 9. Добавление функции handle_user_partial в handle_cached_user
function handle_cached_user() {
var login_cookie = readCookie('login');
var logged_in = document.getElementById('logged_in');
var logged_out = document.getElementById('logged_out');
if(login_cookie == null) {
logged_in.style.display = 'none';
logged_out.style.display = 'block';
} else {
handle_user_partial();
logged_out.style.display = 'none';
logged_in.style.display = 'block';
}
}
Обратите внимание на дополнительную строчку в handle_cached_user в условии else. Эта строка выполнит необходимые подстановки перед тем, как отобразить все DOM-элементы раздела logged_in. Теперь для кэширования целых страниц осталось только воспользоваться директивами кэширования, о которых шла речь в данной статье и статье, опубликованной в прошлом месяце.
Заключение
Эта передовая технология открыла перед нами множество возможностей. Что касается ChangingThePresent.org, то по нашим оценкам мы сможем кэшировать более 75% наших страниц с использованием очень простых функций очистки, работающих по времени. При использовании чуть более сложных технологий очистки можно будет кэшировать более 90% обращений к нашим страницам или даже больше. А при учете наших агрессивных планов по кэшированию изображений, количество обращений к серверу приложений будет составлять только от 1% до 3% всех Web-запросов.
Не забывайте и об обратной стороне медали. Система стала значительно сложнее. Следовательно, придется поддерживать более сложный HTML-код и проверять синхронизацию кодов HTML и JavaScript. Однако явным преимуществом описанного подхода является возможность повышения производительности на основе использования простого и эффективного механизма кэширования. Данный подход можно опробовать, зайдя на ChangingThePresent.org и загрузив домашнюю страницу. Затем загрузите все меню верхнего уровня. Вы обнаружите, что кэшированию подлежат 4 из 6 пунктов меню верхнего уровня. Создайте учетную запись и загрузите все меню заново. Сможете угадать, какие страницы кэшируются? В следующей статье речь пойдёт о технологиях, которые помогут повысить производительность ActiveRecord, и мы продолжим изучение практического использования Rails.
РесурсыНаучитьсяОригинал статьи: Real world Rails, Part 2: Advanced page caching (EN).Все статьи серии
Практическое использование Rails
.
Библиотека JavaScript Prototype: библиотека, упрощающая навигацию по HTML DOM-деревьям.(EN)
От Java к Ruby: что должен знать ваш менеджер
(Pragmatic Bookshelf, 2006): книга автора этой статьи о том, когда и где имеет смысл перейти от языка программирования Java к Ruby on Rails и как это сделать.(EN)
Changing The Present: благотворительный сайт, на котором можно отдать в дар акр тропического леса, помочь вернуть зрение слепому или пожертвовать час времени на исследование рака. Этот сайт положен в основу данной серии статей.(EN)
Улучшенное кэширование страниц с Ruby on Rails: в данной статье рассказывается о более сложных технологиях кэширования страниц и рассматривается JavaScript, который является основой для кода, реализующего чтение cookie-файлов Rails. В статье приведено подробное описание методов обеспечения безопасности на основе ролей и их связь с кэшированием страниц. (EN)Получить продукты и технологии
Ruby on Rails: загрузите Web-среду Ruby on Rails с открытыми исходным кодом.(EN)ОбсудитьПримите участие в обсуждении материала на форуме.Об автореБрюс Тэйт (Bruce Tate) является отцом, горным байкером и байдарочником, проживающим в Austin, Texas. Он автор трех бестселлеров по языку Java, в том числе, победителя Jolt "Лучше, быстрее, легче Java". Недавно издал "За пределами Java"… Он работал 13 лет в IBM, а сейчас является основателем RapidRed consultancy, где специализируется на стратегиях и архитектурах облегченной разработки, основанных на технологии Java и Ruby on Rails.Выскажите мнение об этой страницеПожалуйста, найдите минутку и заполните форму, чтобы повысить уровень сервиса.Помогла ли данная информация достичь Вашей цели?ДаНетНе знаю Пожалуйста, напишите комментарий, чтобы мы могли улучшить данную страницу: Насколько полезна эта информация?
(1 = Бесполезна,
5 = Очень полезна)12345 В началоIBM обладает всеми авторскими правами касательно информации, расположенной на developerWorks. Использование информации приведенной на этом ресурсе без явного письменного разрешения от IBM или первоначального автора запрещены. Если Вы желаете использовать информацию с developerWorks, пожалуйста воспользуйтесь регистрационной формой для того, чтобы связаться с нами запрос на использование материалов developerWorks Россия.
IBM в России
Конфиденциальность
Контакты
.