Заметки о релизе Ruby on Rails 3.0

Rails 3.0 это волшебство! Он приготовит вам ужин и постирает белье. Вы не сможете понять как вы жили без него. Это Лучшая Версия Rails, Какой Еще Не Было!

Но если серьезно, это действительно замечательная вещь. В него вложены все замечательные идеи, внесенные присоединившейся командой Merb, сделан фокус на минимизацию и скорость фреймворка и удобный API. Если вы переходите на Rails 3.0 с Merb 1.x, то вам многое будет знакомым. Если переходите с Rails 2.x, то вы его тоже полюбите.

Даже если вам не интересны подробности об оптимизации “внутренностей”, в Rails 3.0 есть что показать. У нас много новых возможностей и улучшений API. Сейчас очень подходящий момент стать разработчиком на Rails. Некоторые из ключевых возможностей:

Помимо всего этого, мы попытались как можно лучше указать об устаревании прежнего API с помощью хороших предупреждений. Это означает, что можно перенести ваше существующее приложение на Rails 3 без необходимости немедленного переписывания всего вашего старого кода в соответствии с последними best practices.

Эти заметки о релизе покрывают основные обновления, но не включают все мелкие багфиксы и изменения. Rails 3.0 содержит почти 4,000 комитов от более чем 250 авторов! Чтобы увидеть все, обратитесь к списку комитов в главном репозитории Rails на GitHub.

Чтобы установить Rails 3:

# Используйте sudo, если этого требует установка
$ gem install rails

Обновление до Rails 3

Если обновляете существующее приложение, было бы хорошо иметь перед этим покрытие тестами. Также, до попытки обновиться до Rails 3, необходимо сначала обновиться до Rails 2.3.5 и убедиться, что приложение все еще выполняется так, как нужно. Затем нужно предпринять следующие изменения:

Rails 3 требует как минимум Ruby 1.8.7

Rails 3.0 требует Ruby 1.8.7 или выше. Поддержка всех прежних версий Ruby была официально прекращена, и следует обновиться как можно быстрее. Rails 3.0 также совместим с Ruby 1.9.2.

Отметьте, что в Ruby 1.8.7 p248 и p249 имеются ошибки маршализации, ломающие Rails 3.0. Хотя в Ruby Enterprise Edition это было исправлено, начиная с релиза 1.8.7-2010.02. В ветке 1.9, Ruby 1.9.1 не пригоден к использованию, поскольку он иногда вылетает в Rails 3.0, поэтому, если хотите использовать Rails 3.0 с 1.9.x перепрыгивайте на 1.9.2 для гладкой работы.

Объект Rails Application

Как часть внутренней работы по поддержке запуска нескольких приложений Rails в одном процессе, Rails 3 представляет концепцию объекта Application. Этот объект содержит все настройки, специфичные для приложения, и очень похож по сути на config/environment.rb из прежних версий Rails.

Теперь каждое приложение Rails должно иметь соответствующий объект application. Этот объект определяется в config/application.rb. При обновлении существующего приложения до Rails 3, необходимо добавить этот файл и переместить подходящие конфигурации из config/environment.rb в config/application.rb.

script/* заменен на script/rails

Новый script/rails заменяет все ранее использовавшиеся скрипты из директории script. Впрочем, сейчас не нужно запусать даже script/rails, команда rails обнаруживает его при вызове из корня приложения Rails и запускает этот скрипт. Пример изменившегося использования:

$ rails console                      # вместо script/console
$ rails g scaffold post title:string # вместо script/generate scaffold post title:string

Запустите rails —help, чтобы увидеть список всех опций.

Зависимости и config.gem

Метода config.gem больше нет, он был заменен использованием bundler и Gemfile, смотрите Внешние Гемы ниже.

Процесс обновления

Для помощи в процессе обновления был создан плагин Rails Upgrade, для автоматизации его части.

Просто установите плагин, затем запустите rake rails:upgrade:check для проверки, какие части вашего приложения следует обновить (с ссылками на информацию, как это сделать). Он также предлагает задание по созданию Gemfile, основанного на текущих вызовах config.gem, и задание по созданию нового маршрутного файла из старого. Чтобы получить плагин, просто запустите:

$ ruby script/plugin install git://github.com/rails/rails_upgrade.git

Пример того, как это все работает, можно увидеть в Rails Upgrade is now an Official Plugin

Помимо Rails Upgrade tool, если нужна помощь, есть люди в IRC и rubyonrails-talk, которые, возможно, сталкивались с подобными проблемами. Напишите в свой блог о своем опыте обновления, чтобы другие смогли воспользоваться вашими знаниями!

Подробнее – The Path to Rails 3: Approaching the upgrade

Создание приложения Rails 3.0

# You should have the 'rails' rubygem installed
$ rails new myapp
$ cd myapp

Сторонние гемы

Сейчас Rails использует Gemfile в корне приложения, чтобы определить гемы, требуемые для запуска вашего приложения. Этот Gemfile обрабатывается Bundler, который затем устанавливает все зависимости. Он может даже установить все зависимости локально в ваше приложение, и оно не будет зависеть от системных гемов.

Подробнее: – bundler homepage

Живите на грани

Bundler и Gemfile замораживает ваше приложение Rails с помощью отдельной команды bundle, поэтому rake freeze более не актуальна и была отброшена.

Если хотите установить напрямую из репозитория Git, передайте флажок --edge:

$ rails new myapp --edge

Если у вас есть локальная копия репозитория Rails, и вы хотите создать приложение с ее использованием, передайте флажок --dev:

$ ruby /path/to/rails/bin/rails new myapp --dev

Архитектурные изменения Rails

Имеется шесть больших изменений в архитектуре Rails.

Railties Restrung

Railties был обновлен, чтобы предоставить совместимое с плагинами API для всего фреймворка Rails, а также полностью переписаны генераторы и зависимости Rails, в результате разработчики смогут в значительной степени внедрять свой код в генераторы и фреймворк приложения совместимым и определенным образом.

Все основные компоненты Rails были разделены

В связи со слиянием Merb и Rails, одной из крупных работ было устранение тесно связанных вместе основных компонентов Rails. Это было достигнуто, и теперь все основные компоненты Rails используют то же API, что вы можете использовать для своих плагинов. Это означает, что каждый сделанный вами плагин или замена любого основного компонента (например DataMapper или Sequel) имеют доступ ко всему функционалу, к которому имеют доступ основные компоненты Rails, и могут расширять и улучшать его как угодно.

Подробнее: – The Great Decoupling

Абстракция Active Model

Частью разделения основных компонентов было выделение всех связей из Action Pack в Active Record. Теперь это выполнено. Всем новым плагинам ORM теперь всего лишь нужно внедрить интерфейсы Active Model, чтобы работать с Action Pack.

Подробнее: – Make Any Ruby Object Feel Like ActiveRecord

Абстракция контроллера

Другой крупной частью разделения основных компонентов было создание основного суперкласса, отделенного от терминов HTTP, для управления рендерингом вьюх и т.д. Создание AbstractController позволило существенно упростить ActionController и ActionMailer, убрав общий код из этих библиотек, и поместив его в Abstract Controller.

Подробнее: – Rails Edge Architecture

Интеграция Arel

Arel (или Active Relation) был принят в качестве основы Active Record, и теперь требуется в Rails. Arel предоставляет абстракцию SQL, упрощающую Active Record и предоставляющую основы для функционала relation в Active Record.

Подробнее: – Why I wrote Arel.

Извлечение Mail

В Action Mailer с самого начала были monkey патчи, пре-парсеры и даже агенты для отправки и получения, все в добавок к встроенному в исходик TMail. Версия 3 изменила все это, так что весь функционал, связанный с сообщениями email был выделен в гем Mail. Это, опять же, уменьшило повторение кода и помогло определить границы между Action Mailer и парсером email.

Подробнее: – New Action Mailer API in Rails 3

Интернационализация

В Rails 3 было проделано много работы над поддержкой I18n, включая гем I18n, поддерживающий разные улучшения производительности.

Подробнее: – Rails 3 I18n changes

Railties

В связи с разделением главных фреймворков Rails, в Railties проведена огромная переделка, чтобы он связывал фреймворки, engine-ы или плагины настолько просто и безболезненно, насколько это возможно:

Генератор приложения получает дополнительные флажки, позволяющие опустить установку test-unit, Active Record, Prototype и Git. Также добавлен новый флажок —dev, настраивающий приложение с Gemfile, указывающим на вашу версию Rails (определенную путем к исходникам rails). Подробнее смотрите rails —help.

Генераторы Railties требуют большого внимания, основываясь на том, что:

Также несколько переделаны вьюхи, создаваемые генераторами Railties:

Наконец, ряд улучшений был добавлен в рейк-таски:

Теперь Railties объявил устаревшим:

PLUGIN/rails/tasks и PLUGIN/tasks больше не загружаются, все таски теперь должны быть в PLUGIN/lib/tasks.

Подробнее:

Action Pack

В Action Pack произошло множество внутренних и внешних изменений.

Abstract Controller

В Abstract Controller были извлечены части общего назначения из Action Controller в виде модуля, годного в использовнии любой библиотекой, используемой для рендеринга шаблонов или партиалов, хелперов, переводов, логирования и любой части цикла отклика на запрос. Теперь эта абстракция позволяет ActionMailer::Base быть унаследованным от AbstractController и всего лишь оборачивать Rails DSL в гем Mail.

Это также предоставило возможность вычистить Action Controller, упростив его код.

Однако отметьте, что Abstract Controller не имеет публичного API, и его не стоит запускать в повседневном использовании Rails.

Подробнее: – Rails Edge Architecture

Action Controller

Устарело:

Подробнее:

Action Dispatch

Action Dispatch это новшество в Rails 3.0, он представляет новую, более чистую реализацию роутинга.

# Вместо:

ActionController::Routing::Routes.draw do |map|
  map.resources :posts
end

# Будет:

AppName::Application.routes do
  resources :posts
end
scope 'es' do
  resources :projects, :path_names => { :edit => 'cambiar' }, :path => 'proyecto'
end

# Даст вам экшн edit по адресу /es/proyecto/1/cambiar

Старый стиль команд map все еще работает, как и прежде, для обратной совместимости, однако будет убран в релизе 3.1.

Устарело

Подробнее:

Action View

Ненавязчивый JavaScript

Произошло масштабное переписывание хелперов Action View, реализованы хуки Unobtrusive JavaScript (UJS) и убраны старые команды встроенного AJAX. Это позволило Rails использовать любой совместимый драйвер UJS для внедрения хуков UJS в хелперах.

Это означает, что все прежние хелперы remote_<method> были убраны из ядра Rails и перемещены в Prototype Legacy Helper. Для получения хуков UJS в HTML, теперь нужно передать :remote => true. Для примера:

form_for @post, :remote => true

Создаст:

<form action="http://host.com" id="create-post" method="post" data-remote="true">
Хелперы с блоками

Хелперы наподобие form_for или div_for, вставляющие содержимое из блока, теперь используют <%=:

<%= form_for @post do |f| %>
  ...
<% end %>

От ваших собственных подобных хелперов ожидается, что они возвращают строку, а не добавляют к результирующиму буфферу вручную.

Хелперы с другим поведением, наподобие cache или content_for, не затронуты этим изменением, им нужен <% как и прежде.

Другие изменния

Active Model

Active Model это новшество в Rails 3.0. Он представляет уровень абстракции для любой библиотеки ORM для использования во взаимодействии с Rails с применением интерфейса Active Model.

Абстракция ORM и интерфейс Action Pack

Частью разделения основных компонентов было выделение всех связей из Action Pack в Active Record. Теперь это выполнено. Всем новым плагинам ORM теперь всего лишь нужно внедрить интерфейсы Active Model, чтобы работать с Action Pack.

Подробнее: – Make Any Ruby Object Feel Like ActiveRecord

Валидации

Валидации были перемещены из Active Record в Active Model, предоставляя интефейс для валидаций, работающий во всех библиотеках ORM в Rails 3.

Все валидационные методы стиля Rails 2.3 все еще поддерживаются в Rails 3.0, новый метод валидации разработан как дополнительная помощь при валидации модели, а не как замена существующего API.

Также можно передать объект валидатора, который можно повторно использовать в разных моделях, использующих Active Model:

class TitleValidator < ActiveModel::EachValidator
  Titles = ['Mr.', 'Mrs.', 'Dr.']
  def validate_each(record, attribute, value)
    unless Titles.include?(value)
      record.errors[attribute] << 'must be a valid title'
    end
  end
end
class Person
  include ActiveModel::Validations
  attr_accessor :title
  validates :title, :presence => true, :title => true
end

# Или для Active Record

class Person < ActiveRecord::Base
  validates :title, :presence => true, :title => true
end

Также есть поддержка самоанализа:

User.validators
User.validators_on(:login)

Подробнее:

Active Record

Active Record было уделено много внимания в Rails 3.0, включая абстрагирование в Active Model, полное обновление интерфейса запросов с применением Arel, обновления валидаций и многие улучшения и фиксы. Rails 2.x API будет полностью поддерживаемым с целью совместимости, до версии 3.1.

Интерфейс запросов

Теперь Active Record, благодаря использованию Arel, возвращает relations на свои основные методы. Существующее API Rails 2.3.x все еще поддерживается и не будет объявлено устаревшим до Rails 3.1, и не будет убрано до Rails 3.2, однако новое API представляет следующие новые методы, все возвращающие relations, позволяющие сцеплять их вместе:

Подробнее:

Улучшения

Патчи и устаревания

Кроме того, в ветке Active Record сделано много фиксов:

А также следующее объявлено устаревшим:

Хотя реализация State Machine была в ветке Active Record несколько месяцев, она была убрана из релиза Rails 3.0.

Active Resource

Часть Active Resource также была извлечена в Active Model, позволив легко использовать объекты Active Resource с Action Pack.

Устарело:

Active Support

В Active Support были направлены большие усилия на то, чтобы сделать его раздробленным, это означает, что вам больше не нужно требовать всю библиотеку Active Support, чтобы пользоваться ее частью. Это позволило различным частям основных компонент Rails выполняться быстрее.

Вот основные изменения в Active Support:

Следующие методы были убраны, поскольку они теперь доступны в Ruby 1.8.7 и 1.9.

Патч безопасности для REXML остался в Active Support, поскольку ранним версиям Ruby 1.8.7 он все еще нужен. Active Support знает, нужно его применять или нет.

Следующие методы были убраны, поскольку они больше не используются во фреймворке:

Action Mailer

Action Mailer получил новый API в связи с заменой TMail на новый Mail качестве библиотеки Email. В самом Action Mailer была переписана практически каждая строчка кода. В результате теперь Action Mailer просто наследуется от Abstract Controller и оборачивает гем Mail в Rails DSL. Это значительно уменьшило количество кода и дублирование других библиотек в Action Mailer.

Устарело:

Подробнее: