Ruby on Rails 3 — Заметки к финальному релизу

Original author: Mikel Lindsaar
  • Translation

Оглавление

  1. Переход на Rails 3.0
    • Rails 3 требует Ruby 1.8.7+
    • Объект Application в Rails
    • script/* заменен на script/rails
    • Зависимости и config.gem
    • Процесс перехода
  2. Создание приложения на Rails 3.0
    • Включение гемов
    • Жизнь на грани
  3. Архитектурные изменения
    • Перезарядка Railties
    • Все компоненты ядра Rails теперь независимы
    • Абстракция Active Model
    • Абстракция контроллеров
    • Интеграция Arel
    • Извлечение Mail
  4. Документация
  5. Интернационализация
  6. Railties
  7. Action Pack
    • Абстрактный контроллер
    • Action Controller
    • Action Dispatch
    • Action View
  8. Active Model
    • Абстракция ORM и интерфейс c Action Pack
    • Валидации
  9. Active Record
    • Интерфейс запросов
    • Усовершенствования
    • Патчи и устаревшие методы
  10. Active Resourсe
  11. Active Support
  12. Action Mailers
  13. О создателях

Введение


Ruby on Rails 3.0 вышел! Он будет готовить за вас ужин и заполнять стиральную машинку бельем. Вы еще будете удивляться, как раньше без него жили. Это лучшие рельсы, которые мы когда-либо делали!

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

Но даже если вам нет дела до внутренней чистки кода, вы всё-равно неприменно почувствуете весь вкус Rails 3.0. Мы приготовили целый букет новых возможностей и обновленных API. Самое время становится разработчиком Rails. Вот основные из изменений:
  • Совершенно новый роутер в RESTful-стиле;
  • Новый API для Action Mailer, созданный по образу и подобию Action Controller (отныне без адской отправки сообщений из нескольких частей);
  • Язык для создания цепочки запросов в Active Record, построеный на базе реляционной алгебры;
  • Ненавязчивые хелперы Javascript с драйверами для Prototype, jQuery и, в ближайшем будущем, других фреймворков (конец inline JS'у);
  • Явное управление зависимостиями с Bundler-ом.
В довесок ко всему этому мы постарались наилучшим образом выделить устаревшие API, снабдив соответствующие компоненты специальными сообщениями. Т.е. для того, чтобы уже сейчас обновиться до версии Rails 3.0, не нужно переписывать весь существующий код для соответствия всем нововведениям.

Данные заметки к релизу покрывают только основные нововведения, но отнють не каждый багфикс или мелкое изменение. Rails 3.0 состоит около 4,000 коммитов от более чем 1,600 авторов! Если вам необходимо узнать всё до мелочей, обратите внимание на список всех коммитов.

1. Переход на Rails 3


Как обычно, при переходе на новую версию лучше всего, чтобы ваш код был максимально покрыт тестами. И, для начала, вам лучше обновится до 2.3.5 чтобы убедиться, что ваше приложение исправно работает еще до перехода на Rails 3.0.

1.1 Rails 3.0 требует Ruby 1.8.7+


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

Имейте ввиду, что в Ruby 1.8.7 p248 и p249 присутствуют marshaling bugs, которые крашат Rails 3.0. В Ruby Enterprise Edition это исправлено начиная с версии 1.8.7-2010.02. Что касается 1.9, то Ruby 1.9.1 также нельзя использовать т.к. в Rails 3.0 он вызывает ошибки сегментации (segfaults). Таким образом, если вы хотите использовать Rails 3.0 ветке Ruby 1.9, прыгайте сразу на 1.9.2.

1.2 Объект Application


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

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

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


Новый script/rails теперь заменяет все скрипты в соответствующей папке. Но не нужно обращаться к script/rails напрямую — достаточно запустить команду rails из корня приложения, которая, в контексте вашего приложения, выполнит указанный скрипт. Например:
rails console # => ./script/console
rails g scaffold post title:string # => ./script/generate scaffold post title:string
Команда rails –help любезно предоставит весь перечен доступных опций.

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


Метод config.gem ушел в небытие в пользу bundler’a и Gemfile’a (см. ниже «Включение гемов»)

1.5 Процесс перехода


Для автоматизации и упрощения процесса перехода был создан специальный плагин — Rails Upgrade.

Просто установите плагин и запустите $ rake rails:upgrade:check чтобы узнать, какие из существующих частей вашей программы нуждаются в обновлении (c сылками на информацию о том как и что обновлять). Также в плагине присутствует таск для генерации Gemfile, основанного на существующих вызовах в config.gem и таск для генерации нового файла с роутами на основе старого. Чтобы скачать плагин, просто выполните следующее — $ script/plugin install git://github.com/rails/rails_upgrade.git.

Узнать на примере, как всё это работает, можно по ссылке Rails Upgrade is now an Official Plugin.

С другой стороны, если вам нужно больше помощи, всегда можно обратиться к людям на IRC канале или в рассылке rubyonrails-talk, которые, вероятно, занимаются тем же что и вы, и возможно даже сталкиваются с такими-же проблемами. Когда у вас наконец всё получиться — не забудте написать в своем блоге, чтобы поделится опытом с другими!

Дополнительная информацияThe Path to Rails 3: Approaching the upgrade.

2. Создания нового Rails-приложенияя


Последовательность на данный момент выглядит вот так:
$ gem install rails --version 3.0.0
$ rails myapp
$ cd myapp

2.1 Включение гемов


Rails теперь использует Gemfile, чтобы знать какие плагины необходимы для запуска вашего приложения. Для чтения и работы с этим файлом существует новый гем bundler, который, помещает все нужные гемы в каталог vendor, изолируя тем самым ваше приложение от системных гемов.

Дополнительная информацияUsing bundler.

2.2 Жизнь на грани


Теперь, благодаря bundler-у и Gemfile-у, для того чтобы «заморозить» ваше приложение, достаточно выполнить специальную команду bundle-ра — прощай rake freeze!..

Ну а если вы используете код из ветки master репозитория Rails, то для создания приложения просто передайте флаг --dev:
$ rails myapp —edge

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


Архитектура Rails претерпела 6 значительных зменений.

3.1 Перезарядка Railties


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

3.2 Все компоненты ядра Rails теперь независимы


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

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

Дополнительная информацияThe Great Decoupling

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


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

Дополнительная информацияActiveModel: пусть любой Ruby объект почувствует себя ActiveRecord

3.4 Абстрактный контроллер


Друго значительной частью в работе над разделением компонетов в ядре стало создание базового суперкласса, изолированого от HTTP, для того, чтобы заниматся рендерингом шаблонов и пр. Создание Abstract Controller'a позволило значительно упросить Action Controller и Action Mailer путем извлечения общего для обоих кода в Abstract Controller.

Дополнительная информацияRails Edge Architecture.

3.5 Интеграция Arel


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

Дополнительная информацияWhy I wrote Arel.

3.6 Извлечение Mail


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

Дополнительная информацияNew Action Mailer API in Rails 3.

4. Документация


Документация ко всем изменениям в API находится в процессе обновления. В добавок к этому руководства Rails Edge также обновляются чтобы соответстовать всем изменениям в Rails 3.0. Тем не менее, руководства на guides.rubyonrails.org будут соответствовать лишь последне стабильной версии (т.е. версии 2.3.5, вплоть до окончательного релиза 3.0).

Дополнительная информацияRails Documentation Projects.

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


В Rails 3 значительный объем работы был проделан над поддержкой интернационализации. Последняя версия гема i18n включена и несет значительную оптимизацию скорости работы.
  • I18n в каждый дом — теперь, по желанию, l18n можно внедрить в любой объект, добавив в него include модулей ActiveModel::Translation и ActiveModel::Validations. Кроме того добавлена поддержка перевода для errors.messages.
  • У атрибутов теперь можно установить язык по умолчанию.
  • Теги формы автоматически определяя статус объекта (Create или Update), подтягивают правильный язык перевода.
  • Тег Label с l18n теперь работает правильно — достаточно передать ему имя атрибута.
Дополнительная информацияRails 3 I18n changes.

6. Railties


Вместе с разделением главных компонентов внутри Rails, Railities были тщательно переработаны для того, чтобы облегчить взаимодействие между фреймворками, движками и плагинами, делая это максимально безболезненно и гибко:
  • Каждому приложению отныне присваиватся свое собственное пространство имен (к примеру, запуск приложение выполняется так: YourAppName.boot), что делает взаимодействие между приложениями значительно проще.
  • Теперь можно обратиться к Rails.config, где доступно огромное множество настроек конфигурации вашего приложения.
  • Всё внутри Rails.root/app теперь автоматически добавляется к load path, поэтому теперь можно, скажем, добавить файл app/observers/user_observer.rb, и Rails просто подгрузит его.
В начале генерации приложения теперь можно использовать несколько новых флагов, среди которых флаги, позволяющие пропустить установку таких компонентов, как test-unit, Active Record, Prototype и Git. Кроме того, благодаря новому флагу -dev, при установке приложения Gemfile берется из текущего репозитория Rails. См. rails –help для справки.

Генераторам различных Railities было уделено огромное количество внимания. Вкратце:
  • Генераторы были переписаны с нуля и более не являются обратно совместимыми.
  • API шаблонов и генераторов были соединены воедино.
  • Генераторы больше не загружаются из специального пути (load path), а просто подгружаются из пути загрузки (Ruby load path), поэтому вызов script/generate foo сделает тоже, что и generators/foo_generator
  • Теперь к генератором можно легко подключить любой новый движок шаблонов, ORM или фреймворк для тестирования.
  • В новых генераторах можно легко переписывать исходные шаблоны, просто положив нужный файл в RAILS_ROOT/lib/templates.
  • Появился Rails::Generators::TestCase, благодаря которому можно создавать и тестировать собственные генераторы.
Кроме того, генерируемые view также получили некоторые усовершенствования:
  • В генерируемых вьюшках теперь используются теги div вместо p.
  • При генерации форм c помощью scaffold, вместо того чтобы дублировать код во вьюшках edit и new, теперь используется partial с припиской _form
  • При генерации форм c помощью scaffold теперь используется f.submit, который возвращает “Create ModelName” или “Update ModelName”, в зависимости от состояния в котором пришел объект
Наконец, улучшения коснулись и rake тасков:
  • Был добавлен таск rake db:forward, благодаря которому теперь можно крутить миграции вперед индивидуально или в группах.
  • Был добавлен таск rake routes CONTROLLER=x, что позволяет теперь просматривать роуты для одного конкретного контроллера.
Признано устаревшими:
  • RAILS_ROOT в пользу Rails.root,
  • RAILS_ENV в пользу Rails.env,
  • RAILS_DEFAULT_LOGGER в пользу Rails.logger.
PLUGIN/rails/tasks и PLUGIN/tasks больше не загружаются — все задачи должны находится в каталоге PLUGIN/lib/tasks.

Дополнительная информация:

7. Action Pack


Action Pack претерпел значительные внутренние и внешние изменения.

7.1 Abstract Controller


Из Action Controller’a в Abstract Controller, в виде модулей, были вынесены основные части, которые теперь могут быть использованы при рендере шаблонов, partial’ов, helper'ов, интернационализации, логирования и любой другой части цикла «запрос-ответ». Благодаря данной абстракции ActionMailer::Base теперь просто наследуется от Abstract Controller’a, являясь, всеголишь, оберткой над Rails DSL в виде гема Mail.

Вынесение в Abstract Controller всего, что только можно было, позволило значительно облегчить Action Controller. Тем не менее следует учитывать, что программисты не смогут напрямую обращаться к Abstract Controller’у, это не API.

Дополнительная информация — Rails Edge Architecture.

7.2 Action Controller

  • В application_controller.rb отныне protect_from_forgery установлен по умолчанию.
  • cookie_verifier_secret был признан устаревшим. Теперь вместо него следует обращаться к Rails.application.config.cookie_secret, а его реализация теперь находится в отдельном файле initializers/cookie_verification_secret.rb
  • session_store был перемещен в initializers/session_store.rb
  • cookies.secure теперь позволяет устанавливать зашифрованные значения в хеше cookie: cookie.secure[:key] => value
  • cookies.permanent теперь позволяет устанавливать постоянные значения в хеше cookie: cookie.permanent[:key] => value, которое вызывает исключение в случае, если верификация оказалась безуспешной
  • теперь можно передавать notice => ‘Это flash-сообщение’ или :alert => ‘Что-то пошло не так’ для вызова format в блоке respond_to. Хеш flash[] по прежнему в строю
  • respond_with был добавлен к контроллерам, упростив тем самым устаревшие format блоки
  • был добавлен ActionController::Responder, при помощи которого можно гибко генерировать ответы (responses)
Признаны устаревшими:
  • filter_parameter_logging в пользу config.filter_parameters << :password
Дополнительная информация:

7.3 Action Dispatch


Введенный в Rails 3.0, этот новый компонент призван сильно упростить маршрутизацию.
  • после сильной чистки и переписывания раутинга, отныне router — это rack_mount над Rails DLS, т.е. по сути он теперь является отдельным небольшим приложением
  • роуты, объявленные в приложении теперь находятся в пространстве имен модуля Application. Т.е. теперь вместо:
    ActionController::Routing::Routes.draw do
    map.resources :posts
    end
    Нужно писать:
    AppName::Application.routes do
    resources :posts
    end
  • добавлен метод match, так что теперь на подходящий (matched) роут можно навесить Rack-приложение
  • добавлен метод constraints, давая возможность защищать свои роуты условиями
  • добавлен метод scope, с помощью которого можно можно помещать роуты в пространства имен (к примеру, для различных языков или особых действией). Например, следующий код:
    scope ‘es’ do
    resources :projects, :path_names => { :edit => ‘cambiar’ }, :as => ‘projeto’
    end
    вызовет метод edit по адресу /es/projeto/1/cambiar
  • добавлен метод root, в виде ярлыка к match ‘/’, :to => path
  • в match можно передавать необязательный сегмент. Так, в match “/:controller(/:action(/:id))(.:format)”, любой заключенный в скобки текст является необязательный
  • роуты могут быть выражены в виде блоков, т.е. теперь к примеру можно писать :home { match ‘/:action’ }
Важно помнить, что устаревшие команды map по прежнему в строю, но с приходом 3.1 они исчезнут окончательно.
Признаны устаревшими:
  • принимающий всё на себя роут для не-REST приложений (/:controller/:action/:id) был закоментирован
  • :path_prefix для роутов убран, а :name_prefix теперь автоматически добавляет "_" в конце переданного значения
Дополнительная информация:

7.4 Action View


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


Значительной ревизии подверглись хелперы в Action View: были внедрены хуки для Unobtrusive JavaScript (UJS), а старые инлайн-AJAX команды канули в лету. Таким образом в Rails теперь можно использовать любой UJS драйвер для реализации UJS хуков в хелперах.

Это означает, что все существующие ранее хелперы remote_ были удалены из рельсов, и теперь находятся в специальном хелпере Prototype Legacy Helper. Теперь, чтобы обратиться к UJS хукам, достаточно передать :remote => true. Так, к примеру:
form_for @post, :remote => true
вернет:
form action="http://host.com" id="create-post" method="post" data-remote="true"

7.4.2 Блочные хелперы


Такие хелперы как form_for или div_for, которые вставляют контент из блока теперь используют <%=:
<%= form_for @post do |f| %>
...
<% end %>


Ваши собственные хелперы такого типа вернут строку, а не допишут в буфер вывода «вручную».

Хелперы другого назначения, такие как cache и content_for, остались нетронутыми.

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

  • Больше не нужно вызывать h(String) для фильтрации HTML — теперь все view генерируются с фильтрацией по умолчанию. Для того чтобы передать нефильтрованую строку, нужнно вызывать raw(string).
  • Хелперы теперь возвращают разметку HTML5.
  • Хелпер label теперь достает данные из I18n одним параметром, т.е. f.label :name сразу вернет переведенный :name.
  • select для I18n теперь вызывается как :en.helpers.select вместо :en.support.select.
  • Не нужно больше ставить знак минус в закрывающем теге ERb-шаблона для того, чтобы избежать перевода сроки.
  • В ActionView добавлен хелпер grouped_collection_select.
  • Добавлен метод content_for? для проверки перед рендерингом, существует ли контент.
  • Передав :value => nil для хелперов формы вы тем самым установите значение поля в nil вместо использования стандартного значения.
  • Передав :id => nil для хелперов формы аттрибует id не будет сгенерирован.
  • Передав :alt => nil для хелпера image_tag вы тем самым установите значение поля в nil вместо использования стандартного значения.

8 Active Model


Active Model — это новый компонент Rails 3.0. Теперь любая ORM библиотека может взаимодействовать с Rails — достаточно лишь воплотить интерфейс Active Model, который является лишь абстрактной прослойкой.

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


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

Дополнительная информацияMake Any Ruby Object Feel Like ActiveRecord

Валидации 8.2


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

Теперь существует метод validates :attribute, options_hash.

В options_hash можно передавать сразу несколько различных валидаций, среди которых:
  • :acceptance => Boolean
  • :confirmation => Boolean
  • :exclusion => { :in => Ennumerable }
  • :inclusion => { :in => Ennumerable }
  • :format => { :with => Regexp, :on => :create }
  • :length => { :maximum => Fixnum }
  • :numericality => Boolean
  • :presence => Boolean
  • :uniqueness => Boolean
ВНИМАНИЕ: Все прежние валидации по прежнему в строю — новый стиль их написания является лишь дополнением (но не заменой) старому.

Также можно передать объект-валидатор, который можно использовать в разных объектах типа ActiveModel. Например:
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


Дополнительная информация:

9. Active Record


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

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


Любой метод в Active Record, благодаря использованию Arel, теперь возвращает relation. Существующий API будет признан устаревшим в Rails 3.1, и полностью удален из фреймворка в версии Rails 3.2. Среди новых методов, которые можно выстраивать в цепочки, присутствуют следующие:
  • where — предоставляет условие для reletion, т.е. что будет выбрано.
  • select — выбор нужного аттрибута из БД.
  • group — группирует relation на предоставленном аттрибуте.
  • having — аналог GROUP BY из SQL.
  • joins — выполняет объеденение relation'a с другой таблицей.
  • clause — аналог JOIN из SQL.
  • includes — включает другие, созданные ранее ralations.
  • order — упорядочивает relation согласно переданному выражению.
  • limit — устанавливает предел количества записей в relation.
  • lock — блокирует пришедшие из БД записи.
  • readonly — возвращает копию данных в режиме доступа «только для чтения».
  • from — дает возможность для relation'a делать выборку из нескольких таблиц.
  • scope — (ранее named_scope) вовзращает объект relation.
  • with_scope — как и with_exclusive_scope, также возвращает объект relation.
  • default_scope — также работает с relation'ами
Дополнительная информация:

9.2 Прочие улучшения


  • добавлен :destroyed? к объектам Active Record
  • добавлен :inverse_of для отношений, позволяя получить уже загрузившееся отношение без обращения к БД

9.3 Патчи и прекращения поддержки


В добавок ко всему, в ветке Active Record произошло множество других изменений:
  • Поддержка SQLite 2 прекращена в пользу SQLite 3.
  • Реализована поддержка для порядка колонок в MySQL.
  • В адаптере для PostgreSQL исправлена TIME_ZONE — больше никаких ошибочных значений.
  • Поддержка нескольких схем для таблиц в PostgreSQL.
  • table_name теперь кешируется.
  • Проведена сильная чистка, на ряду с множественными багфиксами адаптера для БД Oracle.
Кроме того, многие вещи пришлось признать устаревшими:
  • named_scope в Active Record признан устаревшим и переименован в scope
  • в методе scope нужно использовать методы relation'ов вместо поиска в стиле :condition => {}. Например: :since, lambda {|time| where(“created_at > ?”, time) }
  • save(false) признан устаревшим в пользу save(:validate => false)
  • сообщения I18n об ошибке для Active Record необходимо изменить с :en.activerecord.errors.template на :en.errors.template
  • model.errors.onпризнан устаревшим в пользу model.errors[]
  • validates_presence_of теперь стал :presence => true
  • ActiveRecord::Base.colorize_logging и config.active_record.colorize_logging признаны устаревшими в пользу Rails::Subscriber.colorize_logging или config.colorize_logging.
Стоит отметить, что разрабатываемая последние несколько месяцев т.н. State Machine не вошла в Rails 3.0.

10. Active Resourse


Active Resourse также был извлечен в Active Model, что позволило легко использовать объекты Active Resourse в Action Pack.
  • Добавлены валидации благодаря Active Model.
  • Добавлены observing hooks.
  • Поддержка HTTP proxy
  • Добавлена поддежка для digest-аутентификации.
  • Присвоение имен моделям перемещено в Active Model.
  • Аттрибуты Active Resource изменены на хеш с произвольным доступом.
  • Добавлены alias-методы first, last и all для соответствующих scope.
  • find_every больше не возвращает ошибку ResourceNotFound, если ничего не найдено
  • Добавлен save!, который возвращает ResourceInvalid в случае, если объект не valid?.
  • В модели ActiveResource добавлены методы update_attribute и update_attributes.
  • Теперь, для загрзки удаленных ошибок, вместо их content-type используется format Active Resours'a.
  • Для блока схемы (schema block) используется instance_eval.
  • Исправлен ActiveResource::ConnectionError#to_s, где @response не отвечал на #code или #message (...).
  • Добавлена поддержка для ошибок в формате JSON.
  • Обеспечана работа load с массивами чисел.
  • Ответ 410 от удаленного источника, в случае если тот был удален, теперь распознается верно.
  • В Active Resouce добавлена возможно установки опций SSL.
  • Установка таймаута для соединения теперь также влияет на Net::HTTP open_timeout.
Признаны устаревшими:
  • save(false) признан устаревшим в пользу save(:validate => false)
  • Ruby 1.9.2: URI.parse и .decode признаны устаревшими и больше не используются в библиотеке

11. Active Support


Мы достигли большого успеха в работе над Active Support, так что теперь вам не прийдется включать всю библиотеку Active Support только для того, чтобы использовать какое-то небольшое подмножество её функций. Таким образом, множество внутренних модулей Rails начали работать гораздо шустрее.
  • проведена тотальная чистка всей библиотеки, также было убрано множество неиспользуемых методов
  • Active Support больше не предоставляет методы от TZInfo, Memchache Client и Bundle: теперь всё это нужно инклудить отдельно, предварительно установив командой gem bundle
  • добавлен ActiveSupport::SafeBuffer
  • исправлены Array.uniq_by и Array.uniq_by!
  • исправлена ошибка, при которой TimeZone.seconds_to_utc_offset возвращал неверное значение
  • добавлена прослойка ActiveSupport::Notifications
  • ActiveSupport.use_standard_json_time_format теперь по умолчанию true
  • ActiveSupport.escape_html_entities_in_json теперь по умолчанию true
  • Integer#multiple_of? теперь принимает ноль в качестве аргумента, и если само число равно нулю — возвращает false
  • string.chars перемменован в string.mb_chars
  • ActiveSupport::OrderedHash теперь может быть де-сериализован через YAML
  • добавлен парсер на основе SAX для XmlMini, с использованием LibXML и Nokogiri
  • добавлен метод Object#presence, который возвращает объект если он присутствует (иначе — nil)
  • добавлен метод String#exclude? который возвращается отрицание include?
  • добавлен метод to_i в DateTime, в Active Support, так что теперь to_yaml работает верно на моделях с атрибутом DateTime
  • добавлен метод Enumerable#exclude? чтобы составить компанию Enumerable#include?, избежав тем самым конструкций вида !x.include?
  • XSS фильтрация теперь включена по умолчанию
  • добавлена поддержка глубокого слияния в ActiveSupport::HashWithIndifferentAccess
  • Enumerable#sum теперь работает со всеми множествами, даже если они не отвечают на :size
  • inspect на нулевом промежутке времени вместо пустой строки теперь возвращает 0
  • в modelname добавлены element и collection
  • String#to_time и String#to_datetime допускают дробные секунды
  • добавлена поддержка новых колбеков для объекта-фильтра, отвечающего на :before и :after, используемые до и после колбеков
  • метод ActiveSupport::OrderedHash#to_a возвращает упорядоченное множество массивов (совпадает с Hash#to_a из Ruby 1.9)
  • MissingSourseFile присутствует в виде константы, но её значение всегда равно LoadError
  • добавлен Class#class_attribute, благодаря которому можно объявить атрибут уровня класса, чье значение может быть наследовано и переписано дочерними классами
  • наконец-то из ActiveRecord удалены DeprecatedCallbacks
Следующие методы были исключены ввиду того, что они теперь присутствуют в Ruby 1.8.7 и Ruby 1.9:
  • Integer#even? and Integer#odd?
  • String#each_char
  • String#start_with? и String#end_with? (3rd person aliases still kept)
  • String#bytesize
  • Object#tap
  • Symbol#to_proc
  • Object#instance_variable_defined?
  • Enumerable#none?
Патч для безопасности REXML остался в Active Support, так как ранние версии Ruby 1.8.7 по прежнему в нём нуждаются. Active Support знает, когда его нужно применить, а когда нет.

Следующие методы были удалены ввиду своей ненужности:
  • Object#remove_subclasses_of, Object#subclasses_of, Object#extend_with_included_modules_fromObject#extended_by
  • Class#subclasses, Class#reachable?, Class#remove_class
  • Regexp#number_of_captures
  • Regexp.unoptionalize, Regexp.optionalize, Regexp#number_of_captures

12. Action Mailer


С заменой TMail на новый Mail, Action Mailer получил полностью новый API. Сам по себе, Action Mailer был практически полностью переписан. В результате проделанной работы, теперь Action Mailer просто наследуется от Abstract Controller'a, и теперь обертывает Mail gem. Это позволило сократить количество кода и дублирующих библиотек внутри Action Mailer.
  • все отправители теперь по умолчанию находятся в папке app/mailers
  • теперь можно отсылать email, используя новый API с трёмя методами: attachments, headers и mail
  • все методы Action Mailer, связаные с почтой теперь возвращают объект Mail::Message, который далее может быть отправлен собственным методом deliver
  • метод доставки почты теперь может принимать хеш со всеми нужными заголовками письма
  • метод доставки почты теперь работает также как и respond_block в Action Contoller'e, так что теперь можно явно или неявно рендерить шаблоны письма. Кроме того, Action Mailer теперь разделит письмо на несколько частей, если нужно
  • можно передать proc в вызов format.mime_type внутри mail-блока, тем самым явно делая рендер резличных типов текста, или добавляя новые шаблоны или лейауты
  • все unit-тесты mailer'а теперь стали функциональными тестами
Признаны устаревшими
  • :charset, :content_type, :mime_version, :implicit_parts_order признаны устаревшими в пользу соответствующих вызовов в стиле ActionMailer.default :key => value
  • Динамические методы create_method_name и deliver_method_name отныне признаны устаревшими — просто вызывайте method_name, который возвращает объект Mail::Message.
  • ActionMailer.deliver(message) устарел, достаточно вызвать message.deliver.
  • template_root устарел — передавайте опции в вызов рендера внутри Proc-объекта из метода format.mime_type внутри блока генерации mail.
  • Метод body, для определения instance-переменных теперь также устарел (body {:ivar => value}), так что теперь достаточно обьявлять instance-переменные непосредственно внутри метода — они будут видны во вьюшке.
  • Мейлеры теперь перемещены из каталога app/models в app/mailer.
Дополнительная информация:

13. Участники


Обратите внимание на полный список участников, которые провели множество часов внося свой вклад в Rails 3. Честь и хвалам им всем!

PS. Правка форматирования, а также исправление ошибок и неточностей перевода находится в процессе.
PPS. Спасибо maratk за помощь в поиске ошибок!
Share post
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 57

    +4
    Поднял уже 3 проекта на Rails 3 RC и не жалею! Процесс разработки еще быстрее, удобнее и приятней.
    Более того, у меня ощущение, приложения, написанные на Rails 3 у меня занимают в разы меньше времени на поддержку и диагностику возможных проблем.
    Выход релиза очень радует.
      +3
      Тоже уже запустили несколько проектов в продакшине на RC.
      Bundler облегчил работу :)
      Спасибо всем разработчикам!
      0
      Про правку форматирования: может лучше часть введения над хабракатом, а оглавление под ним.
        0
        Ура! Надеюсь перейдем гладко ;)
          0
          блин. немного не вовремя.теперь придётся многое переделывать.
            +1
            Не обязательно же хвататься за голову и бежать переписывать все текущие проекты. Проблем не оберетесь. Это нужно(и то, если существует необходимость) делать размеренно в отдельном бранче.
            Я только один проект перевел с Rails 2.
            +3
            хочется спросить мнение у людей которые имели опыт работы на ZendFramework: ну как вам RoR?

            в целом меня ZF устраивает, но вот PHP после C# немного раздражает. Хотелось бы узнать насколько RoR мощнее\продуманней\удобней чем ZF или наоборот.
              0
              Создатели Ruby – опытные программисты со всего мира, а создатели PHP – опытные программисты из Zend. Zend нацелены на получение прибыли с PHP (дорогущая ZendStudio и т.д., странно, как это ZendFramework не стал платным, но думаю, это дело времени), разработчики Ruby – безумные фанатики занятые разработкой оружия порабощения всего мира!=)
                +2
                спасибо за ответ, но вопрос был именно о ZF vs RoR, а не PHP vs Ruby

                ZF очень удобен, иногда диву даешься, когда узнаешь как некоторые вещи просто и изящно реализованы.
                Так вот хотелось бы узнать мнение о RoR людей которые имели дело с ZF
                  +3
                  Проще самому попробовать чтобы понять разницу. Я как то видел фразу в учебнике по Ruby, что «Ruby — это ваш последний язык программирования, так писать на чём либо другом вы уже никогда не захотите». Я после того как попробовал использовать рельсы два-три года назад (кстати тогда это была версия 1.2) больше ничего другого для веб приложений не использую.
                    –1
                    Меня пока останавливают 3 вещи:
                    1. трудности с хостингом
                    2. просматривая видеокасты я понял что и в рельсах есть минусы незначительные(а где их нет?) после чего возникло ощущение что поменяю шило на мыло (зф на рор)
                    3. единственный язык на котором бы я хотел программировать — C# но к сожалению для массового сайтостроения он малопригоден(много расходов на хостинг итп)

                    определнно попробую как только закончу текущие проекты на ЗФ и высвободится время. Но хочется заранее услышать мнение тех кто перешел или попробовал и не понравилось)
                      0
                      > единственный язык на котором бы я хотел программировать — C#

                      просто вы не знакомы с Ruby

                      а хостинг — для испытаний heriku.com идеален
                        +3
                        Дид ю мин heroku.com?
                          0
                          Да, опечатался, извиняюсь =(
                        +1
                        А зачем вам нужно заниматься массовым сайтостроением? Большинство серьезных сайтов работает на своих серверах и стоит там то, что нужно программистам.

                        Нравится C# — найдите работу на C#.
                          0
                          у меня есть работа на C#, основная)
                          а фриланс у меня на PHP. отчасти изза того, что часть сайтов существующих уже на пыхе, да и с хостингом на python\ruby в зоне kz некоторые проблемы)
                      –2
                      Ruby — magick, magick!
                      Rails — magick, magick, magick!
                        0
                        magic?
                        +1
                        Пытаюсь писать на rails3 после ZF, пока ощущения очень разные. От «ой как круто» до «да чёрт возьми, какого ...»

                        Первое, что очень непривычно — перенос всей валидации в модель, отсутствие понятия «формы» (и сопутствующего — «фильтры») и, на мой взгляд, меньшая гибкость rails3 приложения.

                        Далее скопипастю небольшую запись из своего блога, написанную в «порывах гнева» (ни в коем случае не хочу разводить холивар, просто моё личное мнение как человека, долгое время писавшего на zf и пытающего понять всю красоту rails).

                        — «Programming with a pleasure» – девиз одной из лучших IDE для Ruby и Rails – RubyMine.

                        Действительно, написание простых приложений в rails доставляет неимоверное удовольствие: тут скаффолд, там скаффолд, тут плагин, там плагин, а если приложение не простое или требует создание гибкого интерфейса для пользователя – можно вешаться.

                        Для начала, про магию.

                        *Иногда про неё можно не знать и в итоге понять «что же тут блять происходит» можно только потратив минимум 30 минут на чтение кода самих Rails.
                        *Очевидное не всегда реализовано. Если вам кажется, что будет именно так, как вы хотите – придётся сто раз проверить. И это касается даже самых простых мелочей, расписаных в гайдах.
                        *Чтобы решить проблему придётся рыть и рыть в глубь – Rails на столько разбросан по файлам, на столько наполнен алиасами и псевдо-алиасами, что откопать проблему может быть очень сложно. Конечно, можно сразу писать в багтрекер, но если время не ждёт, то придётся рыть и рыть.

                        А теперь про написание кода
                        *Необходимость постоянно перегружать rails-сервер при изменениях в конфигах, либах и плагинах (во время разработки) неимоверно доставляет, особенно когда с полчаса правишь код, а потом понимаешь что он не работал…потому что rails и не думал, что ты его изменил.
                        *Автоподгрузка. При кажущейся красоте настройки оной, подключить для автоподгрузки lib/* практически нереально
                        *Неочевидность. Для того, что бы что-то заработало, нужно что-то сказать магическое. Про последнее может быть написано 100 страниц в api, но в них не скажут, что необходимо это магическое заюзать, чтобы что-то другое магическое заработало.
                        *Документация. Найти как сделать что-то можно только зная, куда копать.

                        И немного про скорость написания кода.

                        То, что я сейчас пишу уже в течение 2х дней и, видимо, буду писать ещё завтра, на «всеми любимых» php+zf я бы реализовал часа за 2-3.

                        Накипело.

                        Извините, любители рельсов, но накипело, может это не моё, может я такой нуб и идиот…я ещё побьюсь конечно, но чую я, что либо откажусь от них и вернусь полностью на php+zf или буду искать что-то другое, может на других языках.
                        ----
                          +1
                          Спасибо за мнение! Сам уже давно задумал побег с ZF, как только будет релиз третьей рельсы.

                          Я думаю, низкая скорость разработки, первое время, это естественный overhead знакомства с новым фреймворком. В конечном итоге, полагаю, стройность рельсы и синтаксический сахар Ruby дадут явное преимущество. Такие вещи, как например, named scopes, хоть и вполне реализуемы в PHP+ZF, выглядят в последнем инопланетными костылями, когда в Rails это нечто изящное и естественное.
                            +1
                            Добавлю, что вижу проблему Zend Framework не в самом ZF, а в PHP. К сожалению, для ZF ещё не случилось The Great Decoupling, тем не менее, приближаясь к ZF2, он становится заметно стройнее и логичнее.

                            А вообще, если бы у разработчиков ZF был Ruby, то они бы написали Rails.
                              0
                              Дада… побег хочется совершить в основном изза морального устаревания PHP. ни тебе enumerables, ни нормального неймспейсинга.
                            0
                            после пхп меня в рельсах только магия смущает. В пхп все голое
                              +3
                              Ну так магией надо просто научиться пользоваться и тогда она будет экономить вам кучу времени.

                              Для ярых ненавистников магии существует Python и Django.
                              +1
                              все тру — у меня те же самые ощущения — простый сайты по книжки создаются на ура, но как встречаешь проблему, magic рельсов просто начинает выносить мозг.

                              сейчас в качестве прототипа делаю один очень сложный проект на expressjs — пока все очень и очень нравится (ну, единственное что не хватает, это нормальный debug + IDE).
                                0
                                RubyMine не достаточно хорош? Учитывая что он построен на IDEA так же как и PHPStorm то лучшего IDE не бывает
                                  0
                                  эээ вы этот комментарий мне? я вроде не жаловался на RubyMine, хотя мне больше нравится Netbeans. может вы про вторую часть комментария? expressjs это фреймворк для nodejs — а там пока ни IDE (кроме Notepad/TextMate), ни debug (кроме кривого плагина).
                                    0
                                    ааа… пардон, невнимательно читал
                                  0
                                  Что самое интересное, всё как раз с точностью до наоборот:
                                  RoR превосходно подходит для создания сложных веб-приложений, а для создания простеньких сайтов подойдут скорее php-шные CMS'ки.
                                    +1
                                    Согласен. Для простых вещей иногда проще за 15 минут развернутьк акую-нибудь cmsку. А под конкретное ТЗ быстрее, проще, эффективней и качественней выйдет на RoR(в контесте данного треда). Просто нужно понять, как там все работает, экспериментировать.
                                  0
                                  спасибо, наконец-то неофтопиковый коммент. хоть и негативный:)
                                  вот тоже пока от поверхностного рассмотрения рельсов двоякое ощущение: от восхищения до отторжения.

                                  Ну а что можете сказать теперь о минусах ZF относительно RoR?
                                    +2
                                    Я не могу сравнивать непосредственно zf с ror, скорее zf+php с rails+ruby…
                                    Вообще даже такое сравнение достаточно сложно для меня, по скольку к zf я уже привязался.

                                    Но всё же… после написания rails кода в zf сильно не хватает перегрузки. Так чтобы взять и расширить некий класс, заменить его поведение, добавить примесь и т.д., не создавая новый класс. Динамическая модель в ruby просто великолепна.

                                    Не хватает фильтров в контроллере (да, фильтры есть, но их гибкость достигается засчёт ручной реализации того, что в rails уже есть).

                                    ORM модель в zf, хоть и реализует другой паттерн (не activeRecord), всё же имеет много внутренних нелогичностей.
                                    Простой пример. Берём объект, пытаемся сделать выборку с join и… приходится руками указывать текущую таблицу.

                                    Работа с сигнатурами файлов… ZF пытается определить всё сам (где находится база сигнатур), определяет не правильно, после этого при деплое приходится руками на сервере править zf, чтобы он не занимался самодурством.

                                    В общем, если подвести итог — негибкость кода и, иногда, нелогичность, неоднообразность решений. Последнее потихоньку исправляется и я жду не дождусь ZF2.
                                      0
                                      Главный минус ZF — это PHP.
                                      +1
                                      Сначала писал 5 лет на perl. Потом 6 лет на php (ох как я его ненавидел).
                                      Сейчас перехожу с ZF на Rails, пока еще многое дается с трудом, но от одной генерации ресурсов и работы с формами просто кончаю) Теперь работа с формами стала по настоящему легкой. Все больше ненавижу ZF и PHP в часности. Или взять те же mixin'ы, блоки, итераторы — это круто. Раньше мой любимый язык был Перл, теперь — сами догадайтесь какой)
                                        0
                                        А если б вы ещё видели formtastic… :-)
                                          0
                                          Использую и его)
                                        +1
                                        Часто меняемый код лучше помещать в модели и в хелперы, при этом в deve перезагрузка классов автоматическая.

                                        Но вообще странно, я, к примеру, на Рельсах код пишу намного быстрее, чем в Zend Framework.

                                        Для маленьких штучек предпочитаю Sinatra и Node.JS/Express.
                                          0
                                          мы с вами схожи — вообще если руби, я пытаюсь делать на sinatra — как то понятнее для меня, продуктивность на старте может и страдает, зато окупается сопровождение.
                                        +2
                                        Имхо, там основное различие как раз в мощности языков. Страшное $a = array( «key» => «value»); превращается в a = [ :key => «value» ] и т.д. типа method chaining: News.active.by_author(«Smith»).limit(5).
                                        Rails сильнее ZF как раз из-за использования Ruby.
                                          0
                                          Да, в этом я соглашусь, очень часто в голове возникает «вот бы ZF, да на ruby»
                                            0
                                            получается Rail на руби вас устраивал бы меньше чем ZF на руби? )
                                        +2
                                        Я бы больше сравнивал Рельсы с Симфони. Первая версия очень много переняла от рельсов. Но сейчас оба продукта развиваются в сторону децентрализации.

                                        Зенд же изначально был децентрализован, из-за этого терялось много времени при первоначальной сборке проекта (подключение и настройка когнтроллеров, логгеров, дебаггеров и т.п.) Рельсы и симфони включают всё из коробки.

                                        Думаю, Рельсы будут можщнее и удобнее Зенда. А вот к Руби привыкать придется некоторое время.
                                          +1
                                          кстате, я считаю что симфони лучший фреймворк для php
                                            +1
                                            >Рельсы и симфони включают всё из коробки.
                                            ZF включает из коробки всё и даже больше, но его компоненты разработаны и очень удобны для использования в не-ZF проектах.
                                            Многое, что включено в бандл ZF в том же Rails достигается плагинами, даже не знаю что лучше, но несомненный плюс такого подхода в ZF в том, что не приходится выбирать между десятком плагинов и смотреть на совместимость — «если идёт вместе с ZF, значит точно работает».
                                          0
                                          Впечатления только хорошие. Быстрее, приятней, логичней.
                                          +4
                                          спасибо за перевод, большую работу сделали
                                            –1
                                              +2
                                              а мне кажется за Rails будущее web :)
                                                +1
                                                Будущее Web за Javascript.
                                                0
                                                Какое удачное для меня совпадение — начал изучать RoR сразу с 3 беты и к релизу уже буду в силах создать свой первый RoR-сайт!
                                                –2
                                                Поправьте пожалуйста опечатки: Resourse > Resource
                                                Глаз режет.
                                                  –5
                                                  кстати, работаю с рельсами в циклах, как и с ООП.
                                                  ух ты крутатень
                                                  ипать как тут все закручено, они там с ума сошли чтоли?
                                                  а впринципе… клевая вещь
                                                  мама мия, и как мен сделать эту штуку???
                                                  вот как… создатели гениальны
                                                  и по кургу… ООП я тожек сначала отрицал, потом понимал, потом опять…
                                                    0
                                                    Господа, написали бы ещё как запустить рельсы 3, руби 1.9.2 с mysql — было бы отлично. Ну никак не получается справиться с встроенным mysql2. всё время вылазиет pastie.org/1130112
                                                      0
                                                      Нашёл решение.
                                                      описал тут merc.habrahabr.ru/blog/103192/
                                                        0
                                                        А у меня не получилось переехать на Rails 3, уткнулся в это:
                                                        https://rails.lighthouseapp.com/projects/8994/tickets/5557-rails-300-yield-wont-show-block-contents-in-render-layout-if-it-is-placed-after-render-partial
                                                        Надеюсь, скоро починят…

                                                        Only users with full accounts can post comments. Log in, please.