#282 Upgrading to Rails 3.1
Rails 3.1 наконец-то увидел свет. Здесь вы можете ознакомиться с отличным обзором его новых возможностей: Release Notes on the RailsGuides site, некоторые из которых, были показаны на сайте Railscasts а также здесь. В этом эпизоде мы остановимся на обновлении приложения с Rails 3.0 на 3.1 и мы будем использовать сайт Railscasts как пример.
Подготовка сайта
Перед тем как приступить к обновлению, необходимо сделать несколько подготовительных шагов. Если сайт на данный момент работает не на последней версии Rails 3.0, на данный момент 3.0.10, мы должны будем обновить его. Мы можем это сделать, установив версию в Gemfile и затем запустив bundle
.
gem "rails", "3.0.10"
Далее, запускаем набор тестов приложения, чтобы убедиться, что все тесты до сих пор проходят и что не возникает никаких ошибок deprecation. Если такие есть, то мы должны их исправить, прежде чем продолжать. В коде Railscasts все тесты проходят и можно продолжить с обновлением.
Обновление
Мы готовы к тому чтобы начать обновление сайта. Сделаем это в отдельной ветке Git, которую назовем rails31
.
$ git checkout -b rails31
Обновление до Rails 3.1 достаточно простое. Мы просто должны перейти в Gemfile
нашего приложения снова и изменить версию на последнюю версию 3.1, на данный момент 3.1.0
.
gem "rails", "3.1.0"
Теперь можно запустить bundle update
, чтобы установить новую версию. Единственное изменение, которое нужно сделать - изменить файл конфигурации development.rb
, в котором мы должны удалить или закомментировать следующую строку.
# config.action_view.debug_rjs = true
Если мы запустим наши тесты заново, то увидим, что они всё еще проходят. Мы даже можем запустить сервер Rails и увидеть, что всё работает в браузере.
Изменение нашего приложения для использования asset pipeline
Asset pipeline это одна из основных новых возможностей Rails 3.1, но наше приложение до сих пор содержит свои изображение, файлы стилей и JavaScript в директории /public
, и мы вообще не используем ее преимущества. Asset pipeline является абсолютно необязательным и не вступает в силу, пока мы не включим его, поэтому, если мы не уверены в необходимости его использования, то это не должно нас останавливать от обновления на Rails 3.1. Учитывая, как просто можно обновиться, нет причин не делать этого.
Если мы хотим использовать asset pipeline, то мы должны включить его. Чтобы это сделать, нужно добавить следующие строки в Gemfile
. (Это те строки, которые идут в Gemfile
, который генерируется при создании нового Rails 3.1 приложения.)
# Gems used only for assets and not required # in production environments by default. group :assets do gem 'sass-rails', " ~> 3.1.0" gem 'coffee-rails', " ~> 3.1.0" gem 'uglifier' end gem 'jquery-rails'
Этот код создает группу assets
и помещает некоторые необходимые гемы в нее. Также он включает гем jquery-rails
, чтобы возможно было использовать jQuery. (Если вы предпочитаете использовать Prototype, то есть гем prototype-rails
, который вы можете использовать вместо этого.) Также необходимо изменить /config/application.rb
, заменяя этот код:
# If you have a Gemfile, require the gems listed there, including any gems # you've limited to :test, :development, or :production. Bundler.require(:default, Rails.env) if defined?(Bundler)
на этот:
if defined?(Bundler) # If you precompile assets before deploying to production, use this line Bundler.require *Rails.groups(:assets => %w(development test)) # If you want your assets lazily compiled in production, use this line # Bundler.require(:default, :assets, Rails.env) end
Этот код добавляет группу assets
к группам, которые необходимы Bundler
. Понадобится включить asset pipeline также и в этом файле, мы можем это сделать, добавляя следующие строки кода в класс Application
:
# Enable the asset pipeline config.assets.enabled = true # Version of your assets, change this if you want to expire all your assets config.assets.version = '1.0'
Этот код включает asset pipeline и также указывает номер версии. Этот номер можно изменить, когда мы хотим изменить assets.
Также нужно изменить настройки в каждом файле среды. Начнем с development.rb
. Здесь нужно сделать пару изменений, чтобы assets не сжимались и чтобы включить их отладку.
# Do not compress assets config.assets.compress = false # Expands the lines which load the assets config.assets.debug = true
Далее изменим production.rb
.
# Compress JavaScript and CSS config.assets.compress = true # Don't fallback to assets pipeline config.assets.compile = false # Generate digests for assets URLs config.assets.digest = true
В production нам нужно сжатие assets, но мы ставим compile
в false
, чтобы это не влияло на asset pipeline, если мы хотим предварительно скопилировать их. Также мы установим digest
в true
, чтобы URL для assets были подписаны. Мы можем, конечно, сконфигурировать эти опции иначе, чтобы они соотвествовали тому, как наше приложение работает в production.
И, наконец, мы изменим среду тестирования. Здесь нужно добавить опции, чтобы статичные assets обслуживались и кэшировались. И еще мы добавим их отладку.
# Configure static asset server for tests with Cache-Control for performance config.serve_static_assets = true config.static_cache_control = "public, max-age=3600" # Allow pass debug_assets=true as a query parameter to load pages with unpackaged assets config.assets.allow_debugging = true
Если мы используем Git для контроля версий приложения, следует также изменить файл .gitignore
и добавить директорию .sass-cache
в список игнорируемых элементов. Нам не нужно, чтобы кэш SASS попал в Git.
.sass-cache/
Перемещение assets
Теперь наш assets pipeline настроен и настало время для создания директории app/assets
. Затем можно переместить директории images
, javascripts
и stylesheets
из /public
в /app/assets
.
$ mkdir app/assets $ mv public/images/ app/assets/ $ mv public/javascripts/ app/assets/ $ mv public/stylesheets/ app/assets/
Некоторые из файлов, которые мы переместили, больше не нужны, такие как файлы, связанные с jQuery в директории javascripts
. Они включены в гем jQuery, так что мы можем удалить jquery.js
, jquery.min.js
, и rails.js
. Настало время решить, нужно ли переместить некоторые файлы, такие как плагины jQuery в /lib/assets
или /vendor/assets
, как было сделано в эпизоде 279 [посмотреть, прочитать].
Далее нам нужно создать файлы манифестов. В этом приложении уже есть файлы application.js
и application.css
в соответствующих директориях, поэтому нам не нужно их создавать. Начнем с CSS файла. Чтобы превратить его в файл манифеста, нам нужно добавить специальные комментарии наверху, которые скажут Sprockets, какие файлы нужно включать. (Синтаксис Sprockets был хорошо разобран в эпизоде 279). Мы передадим Sprockets включить оставшиеся файлы, а также все другие файлы в директории stylesheets
и ее дочерних папках.
/* *= require_self *= require_tree . */ /* остальная часть файла опущена */
Можно сделать то же самое с файлом application.js
, но нам нужно сделать немного иначе, раз нам нужно также включить jQuery.
//= require jquery //= require jquery_ujs //= require_self //= require_tree . /* остальная часть файла опущена */
И снова мы добавляем здесь require_self
, так как файл и сам содержит код и require_tree
, чтобы другие файлы в данной директории были включены.
Также понадобится зайти в файл layout и изменить строки, которые включают файлы стилей и JavaScript, так, чтобы каждая из них ссылалась только на соответствующий файл приложения, так как остальные файлы будут включены манифестом.
<%= stylesheet_link_tag "application" %> <%= javascript_include_tag "application", "http://cdn.sublimevideo.net/js/3s7oes9q.js" %>
Файлы JavaScript, которые требуются для приложения, включают внешние файлы, которые не будут включены через asset pipeline. Это тот случай, в котором все еще требуется включать их в данный список файлов.
Пришло время проверить наше приложение в браузере, чтобы убедиться, что все наши изменения сработали. Однако, прежде, нам нужно запустить bundle
снова, чтобы установить все гемы, которые мы добавили. После того как они установились, мы можем запустить сервер
$ rails s
В основном все работает, но мы до сих пор видим некоторые «сломанные» изображения, например, логотип в шапке страницы.
Проблема с этим изображением в том, что его URL был статично вписан в файл layout.
<img src="/images/railscasts_logo.png" width="423" height="56" alt="RailsCasts = Ruby on Rails Screencasts"/>
Так случилось, потому что изображения в нашем приложении больше не находятся в директории /public/images
. Простейшим решением может показаться изменить URL изображения с /images/railscasts_logo.png
на /assets/railscasts_logo.png
, и если это и заработает в development, то у нас возникнут проблемы в production. Если у нас включена опция assets.digest
, то хэш будет добавлен к концу имени файла, таким образом, статичная ссылка не будет больше работать. Вместо этого мы должны всегда использовать хелперы. Это свяжет изображение корректно, как в development, так и в production.
<%= image_tag("railscasts_logo.png", :size => "423x56", :alt => "RailsCasts - Ruby on Rails Screencasts") %>
Нужно будет пройтись по всему приложению и изменить все встречающиеся статичные ссылки на assets так, чтобы они использовали хелперы, как и изображение выше. Если мы перезагрузим страницу, то теперь изображение появляется, что значит, что наш asset pipeline работает корректно.
Мы в значительной степени закончили обновление нашего приложения до Rails 3.1. Остались еще несколько новых возможностей, от которых можно получить преимущества, стоит просмотреть другие эпизоды по Rails 3.1, чтобы увидеть, будут ли они полезны в ваших приложениях.