Обновление сайта до Ruby on Rails 3 - отчет
April 5, 2011 in Ruby on RailsЗа последний месяц я обновил два сайта на Ruby on Rails 3. Первый – RentFeed – обновить было несложно, потому что функционала там немного. На обновление CarGid ушло около 40 человеко-часов; теперь и он работает на Ruby on Rails 3.
До обновления существующего сайта советую ознакомиться с Rails 3 на новом проекте. Нет, не так – считаю, что нельзя обновлять проект, не работав никогда с Rails 3.
Эта статья – не руководство по обновлению, а мои заметки о нем. Полноты раскрытия темы не обещаю.
Мотивация
Зачем тратить 40 часов на то, что не принесет ни новой функциональности, ни новых пользователей, ни существенного прироста производительности? Причины такие:
- Возможность использовать свежие библиотеки. Все больше библиотек перестают поддерживать Rails 2.3, и скоро тебе придется обновляться.
- Исправленные баги и недочеты в безопасности.
- В некоторых местах – намного более красивый и наглядный код. Красивые запросы на Arel в моделях. Лаконичные роуты. Понятные мейлеры.
Мое такое мнение, что обновляться уже пора. После знакомства с третьими рельсами недостатки вторых начинают бросаться в глаза.
Подготовка
Создаем ветку rails3
в репозитории.
Устанавливаем плагин rails_upgrade. Следуя инструкциям плагина, создаем резервные копии ценных файлов, а также создаем новый routes.rb
и application.rb
, и, если bundler еще не задействован, новый Gemfile
. Помимо это, делаем:
rake rails:upgrade:check > upgrade_log.txt
Пригодится.
Коммитим изменения, дабы ничего не потерять.
Подбор гемов
Удаляем плагин rails_upgrade
, ибо он больше не пригодится.
В Gemfile
нужно принудительно указать gem 'rails', '~> 3.0.0'
, а кроме этого, если используется MySQL – то и gem 'mysql2'
. Остальные гемы оставляем без изменений.
Возносим молитвы.
Производим bundle update
. Эта команда попробует подобрать такие версии гемов, которые заработают с Rails 3.
Скорее всего, у нее это не получится. Проблемы с совместимостью решаются гуглением – большая часть гемов уже работает с Rails 3. Заодно пройдись по плагинам – возможно, некоторые из них также уже доступны в виде гемов.
Результатом этого этапа будет успешно собранный Gemfile.lock
; коммитимся.
Установка Rails 3
Выполняем в каталоге проекта
rails .
Да, просто так. Эта команда предложит затереть ряд файлов – разрешаем, ведь все под контролем (версий, в смысле).
Коммитимся. Теоретически проект уже работоспособен (но вряд ли).
Зачистка
Убираем все файлы в script
, кроме script/rails
- они больше не используются.
Меняем mysql
на mysql2
в database.yml
, если используется MySQL.
Заменяем базовый config/application.rb
на тот, который сгенерировали.
Подчищаем роуты
Подставляем тот routes.rb
, который сгенерировали из старых роутов. Увы, скорее всего он сломанный и содержит синтаксические ошибки. Устраняем их.
Вот теперь проект точно должен запуститься.
Модели
В моделях надо будет поменять named_scope
на scope
и переформулировать запросы в Arel. Это пока необязательно.
Контроллеры
В контроллерах ничего особенного не поменялось
Виды
Большая часть времени уйдет именно на обновление видов.
Изменения в Javascript
Разнообразные рельсовые обработчики событий теперь вынесены в отдельный Javascript-файл, что прекрасно. Его нужно подключить. Для jQuery этот файл берется из репозитория rails/jquery-ujs.
Этому файлу нужен authenticity_token
, поэтому в заголовок дописываем
<head>
...
<%=csrf_meta_tag %>
</head>
- style block helpers are deprecated. Please use =
Это такая шутка разработчиков, по-видимому. Везде, где используются блочные хелперы, придется дефис поменять на знак равенства:
<!-- было -->
<%-form_for @foo do %>
<!-- надо -->
<%=form_for @foo do %>
Слава богу, делать это не обязательно. Но ошибки в лог будут сыпаться.
Введение обязательного html_safe
В Rails 3 все строки, выводимые в шаблон, неизбежно проходят через эксейпинг. Это прекрасно, поскольку в 98% случаев ты выводишь текст, требующий оного.
<%=@blog_post.title_needs_to_be_escaped%>
<script>alert('U NO ESCAPE JAVASCRIPT');</script>
Хелперы h
можно не убирать, двойного эскейпинга не произойдет:
<%=h @blog_post.title_needs_to_be_escaped%>
<script>alert('U NO ESCAPE JAVASCRIPT');</script>
Как же выводить текст с тегами? Применять к нему метод String#html_safe
:
<%=@blog_post.nice_text_with_markup%>
<FONT COLOR="#FF00FF">ЛОВИ СИМПАФКУ!</FONT&;gt
<%=@blog_post.nice_text_with_markup.html_safe%>
<FONT COLOR="#FF00FF">ЛОВИ СИМПАФКУ!</FONT>
Получается, во местах, где ты выводишь строку с тегами, придется дописывать html_safe
. Это сложный и кропотливый кусок работы, который нужно сделать в обмен на чистый и безопасный код.
ActionMailer
Синтаксис ActionMailer поменялся. Мейлеры придется переписать, а скорее, переформатировать. Это довольно прозрачный процесс.
Тесты
Разумеется, процесс обновления будет проще, если проект покрыт тестами. Если не покрыт, то, вполне возможно, ты (как и я) решишь заняться тестами перед обновлением. Однако советую начинать сразу после обновления: Rspec 2 работает только с Rails 3.
Обновляем
Скорее всего, ничего кроме исходников обновлять на сервере не придется, поэтому обновление ничем не будет отличаться от обычного деплоя. Возможно, придется сначала обновить на сервере Rubygems и Bundler.
Понравился пост? Купи мне кофе