Заметки о релизе Ruby on Rails 4.0
Ключевые новинки в Rails 4.0:
- Ruby 2.0 предпочтителен; 1.9.3+ требуется
- Строгие параметры (Strong Parameters)
- Turbolinks
- Кэширование "матрешкой" (Russian Doll Caching)
Эти заметки о релизе покрывают только основные обновления. Чтобы узнать о различных багфиксах и изменениях, обратитесь к логам изменений или к списку коммитов в главном репозитории Rails на GitHub.
Обновление до Rails 4.0
Если обновляете существующее приложение, было бы хорошо иметь перед этим покрытие тестами. Также, до попытки обновиться до Rails 4.0, необходимо сначала обновиться до Rails 3.2 и убедиться, что приложение все еще выполняется так, как нужно. Список вещей, которые нужно выполнить при обновлении доступен в руководстве Обновление Ruby on Rails.
TODO: Configuration changes in environment files
Создание приложения Rails 4.0
Необходим установленный RubyGem 'rails'
$ rails new myapp
$ cd myapp
Сторонние гемы
Сейчас Rails использует Gemfile
в корне приложения, чтобы определить гемы, требуемые для запуска вашего приложения. Этот Gemfile
обрабатывается гемом Bundler, который затем устанавливает все зависимости. Он может даже установить все зависимости локально в ваше приложение, и оно не будет зависеть от системных гемов.
Подробнее: - домашняя страница Bundler
Живите на грани
Bundler
и Gemfile
замораживает ваше приложение Rails с помощью новой отдельной команды bundle
. Если хотите установить напрямую из репозитория Git, передайте флажок --edge
:
$ rails new myapp --edge
Если имеется локальная копия репозитория Rails, и необходимо сгенерировать приложение используя ее, передайте флажок --dev
:
$ ruby /path/to/rails/railties/bin/rails new myapp --dev
Основные особенности
Обновление
- Ruby 1.9.3 (коммит) - Предпочтителен Ruby 2.0; требуется 1.9.3+
- Новая политика устареваний - Устаревшие особенности показывают предупреждения в Rails 4.0, и будут убраны в Rails 4.1.
- Кэширование страниц и экшнов ActionPack (коммит) - Кэширование страниц и экшнов было извлечено в отдельный гем. Кэширование страниц и экшнов требовало слишком много человеческого вмешательства (вручную прекращать кэш, когда обновляются лежащие в основе объекты модели). Вместо этого используйте кэширование по принципу "русской матрешки" (Russian doll caching).
- Обсерверы ActiveRecord (коммит) - Обсерверы извлечены в отдельный гем. Обсерверы требовались только для кэширования страниц и экшнов и могли привести к спагетти-коду.
- Хранилище сессии ActiveRecord (коммит) - Хранилище сессии ActiveRecord извлечено в отдельный гем. Хранение сессий в SQL затратное. Используйте вместо него сессии куки, сессии memcache или произвольные хранилища сессии.
- Защита от массового назначения ActiveModel (коммит) - Защита от массового назначения Rails 3 устарела. Вместо нее используйте строгие параметры (strong parameters).
- ActiveResource (коммит) - ActiveResource извлечен в отдельный гем. ActiveResource не был широко используемым.
- убраны vendor/plugins (коммит) - Для управления установленными гемами используйте Gemfile.
ActionPack
- Strong parameters (коммит) - Позволяет обновлять объекты модели только разрешенными параметрами (
params.permit(:title, :text)
). - Routing concerns (коммит) - В маршрутном DSL, выделяет общие подмаршруты (
comments
из/posts/1/comments
and/videos/1/comments
). - ActionController::Live (коммит) - Потоковый JSON с помощью
response.stream
. - Декларативные ETags (коммит) - Добавляет на уровне контроллера дополнения к etag, которые будут частью вычисления etag.
- Кэширование Russian doll (коммит) - Кэширует вложенные фрагменты вьюх. Каждый фрагмент прекращается на основе набора зависимостей (ключа кэширования). Ключ кэширования - это обычно версия шаблона и объект модели.
- Turbolinks (коммит) - Обслуживает только первую страницу HTML. Когда пользователь переходит на следующую страницу, использует pushState для обновления URL и использует AJAX для обновления title и body.
- Извлечение ActionView из ActionController (коммит) - ActionView был отделен от ActionPack, и будет вынесен в отдельный гем в Rails 4.1.
- Независимость от ActiveModel (коммит) - ActionPack больше не зависит от ActiveModel.
Основное
- ActiveModel::Model (коммит) -
ActiveModel::Model
- это миксин, чтобы обычные объекты Ruby могли работать с ActionPack "из коробки" (например,form_for
). - Новый API скоупов (коммит) - Скоупы должны быть всегда вызываемыми.
- Выгрузка кэша схемы (коммит) - Чтобы улучшить время загрузки Rails, вместо загрузки схемы непосредственно из базы данных, загружает схему из файла выгрузки.
- Поддержка указания уровня изоляции транзакции (коммит) - Выбирайте, что более важно - повторяемые чтения или улучшенное быстродействие (менее блокирующее).
- Dalli (коммит) - Используется клиент Dalli в качестве хранилища сессии в memcache.
- start & finish для уведомлений (коммит) - Инструменты Active Support сообщают подписчикам о начале и завершении уведомлений.
- Тредобезопасность по умолчанию (коммит) - Rails может быть запущен на тредовых серверах приложений без дополнительных настроек. Заметка: Проверьте, что используемые вами гемы тредобезопасны.
NOTE: Убедитесь, что используемые вами гемы тредобезопасны.
- Метод PATCH (коммит) - В Rails PATCH заменил PUT. PATCH используется для частичного обновления ресурсов.
Безопасность
- match не соответствует всем методам (коммит) - В маршрутном DSL, match требует указания метода или методов HTTP.
- Сущности html экранируются по умолчанию (коммит) - Строки, рендерящиеся в erb, экранируются, если не обернуты в
raw
, или вызванhtml_safe
. - Новые заголовки безопасности (коммит) - Rails посылает следующие заголовки с каждым запросом HTTP:
X-Frame-Options
(предотвращает кликджекинг, запрещая браузеру встраивать страницу в фрейм),X-XSS-Protection
(говорит браузеру прерывать инъекцию скрипта) иX-Content-Type-Options
(предотвращает открытие браузером jpeg как exe).
Извлечение особенностей в гемы
В Rails 4.0 некоторые особенности были извлечены в гемы. Можно просто добавить извлеченный гем в свой Gemfile
, чтобы вернуть функциональность.
- Динамические и основанные на хэше методы поиска (Github)
- Защита от массового назначения в моделях Active Record (Github, Pull Request)
- ActiveRecord::SessionStore (Github, Pull Request)
- Обсерверы Active Record (Github, Commit)
- Active Resource (Github, Pull Request, Blog)
- Кэширование экшна (Github, Pull Request)
- Кэширование страницы (Github, Pull Request)
- Sprockets (Github)
- Тесты производительности (Github, Pull Request)
Документация
Руководства были переписаны на GitHub Flavored Markdown.
Руководства имеют адаптивный дизайн.
Railties
Обратитесь к Changelog за полными изменениями.
Значимые изменения
Новые места для тестов
test/models
,test/helpers
,test/controllers
иtest/mailers
. Также добавлены соответствующие задачи rake. (Pull Request)Исполняемые файлы приложения теперь находятся в директории
bin/
. Запуститеrake rails:update:bin
чтобы получитьbin/bundle
,bin/rails
иbin/rake
.Тредобезопасность включена по умолчанию
Была убрана возможность использования произвольного билдера, передав
--builder
(или-b
) вrails new
. Вместо нее рассмотрите шаблоны приложения. (Pull Request)
Устаревания
config.threadsafe!
устарело в пользуconfig.eager_load
, которая предоставляет более тонкую настройку того, что будет лениво загружаться.Rails::Plugin
больше нет. Вместо добавления плагинов вvendor/plugins
, используйте гемы, или bundler с путем, или зависимости git.
Action Mailer
Обратитесь к Changelog за полными изменениями.
Значимые изменения
Устаревания
Active Model
Обратитесь к Changelog за полными изменениями.
Значимые изменения
Добавлен
ActiveModel::ForbiddenAttributesProtection
, простой модуль для защиты атрибутов от массового назначения, когда передаются неразрешенные атрибуты.Добавлен
ActiveModel::Model
, примесь, чтобы объекты Ruby могли работать с Action Pack "из коробки".
Устаревания
Active Support
Обратитесь к Changelog за полными изменениями.
Значимые изменения
Заменен устаревший гем
memcache-client
наdalli
вActiveSupport::Cache::MemCacheStore
.Оптимизирован
ActiveSupport::Cache::Entry
для уменьшения расхода памяти и процессора.Словоизменения теперь могут быть определены для локали.
singularize
иpluralize
принимают локаль как дополнительный аргумент.Object#try
теперь будет возвращать nil вместо вызова NoMethodError, если вызывающий объект не реализует этот метод, но все еще можно получить старое поведение, используя новый методObject#try!
.String#to_date
теперь вызываетArgumentError: invalid date
вместоNoMethodError: undefined method 'div' for nil:NilClass
при получения неверной даты. Это то же самое, что иDate.parse
, и он принимает больше неправильных дат, чем 3.x, такие как:# ActiveSupport 3.x "asdf".to_date # => NoMethodError: undefined method `div' for nil:NilClass "333".to_date # => NoMethodError: undefined method `div' for nil:NilClass # ActiveSupport 4 "asdf".to_date # => ArgumentError: invalid date "333".to_date # => Fri, 29 Nov 2013
Устаревания
Устарел метод
ActiveSupport::TestCase#pending
, используйте вместо негоskip
из MiniTest.ActiveSupport::Benchmarkable#silence
устарел из-за недостатков в тредобезопасности. Он будет убран без замен в Rails 4.1.Устарел
ActiveSupport::JSON::Variable
. Определяйте собственные методы#as_json
и#encode_json
для собственных строковых литер JSON.Устарел метод совместимости
Module#local_constant_names
, используйте вместо негоModule#local_constants
(который возвращает символы).Устарел
BufferedLogger
. ИспользуйтеActiveSupport::Logger
илиlogger
из стандартной библиотеки Ruby.Устарели
assert_present
иassert_blank
в пользуassert object.blank?
иassert object.present?
Action Pack
Обратитесь к Changelog за полными изменениями.
Значимые изменения
- Изменена таблица стилей для страниц исключений для режима development. Также дополнительно отображается строчка кода и фрагмент, который вызвал исключение на всех страницах исключений.
Устаревания
Active Record
Обратитесь к Changelog за полными изменениями.
Значимые изменения
Улучшены способы написания миграций
change
, что делает старые методыup
&down
больше не нужными.Методы
drop_table
иremove_column
теперь обратимые, если дана вся необходимая информация. Методremove_column
принимает несколько имен столбцов; вместо использованияremove_columns
(который необратимый). Методchange_table
также обратимый, если его блок не вызываетremove
,change
илиchange_default
Новый метод
reversible
делает возможным определить код для исполнения при выполнении или откате миграции. Смотрите Руководство по миграциямНовый метод
revert
обратит всю миграцию или предоставленный блок. Если миграция откатывается, данная миграция / блок выполняется обычно. Смотрите Руководство по миграциям
Добавлена поддержка массивов PostgreSQL. Для создания столбца array может быть использован любой тип данных, с полной поддержкой миграций и выгрузкой схемы.
Добавлен
Relation#load
для явной загрузки записи и возвратаself
.Model.all
теперь возвращаетActiveRecord::Relation
, а не массив с записями. ИспользуйтеRelation#to_a
, если вы действительно хотите массив. В некоторых особенных случаях это может вызвать повреждения при обновлении.Добавлен
ActiveRecord::Migration.check_pending!
, вызывающий ошибку, если миграции ожидают выполнения.Добавлена поддержка произвольного кодирования для
ActiveRecord::Store
. Теперь можно установить собственное кодирование следующим образом:store :settings, accessors: [ :color, :homepage ], coder: JSON
Соединения
mysql
иmysql2
будут по умолчанию устанавливатьSQL_MODE=STRICT_ALL_TABLES
, чтобы избежать тихих потерь данных. Это может быть отключено, определивstrict: false
вdatabase.yml
.Убрана IdentityMap.
Убран автоматический запуск запросов EXPLAIN. Опция
active_record.auto_explain_threshold_in_seconds
больше не используется и должна быть убрана.Добавлены
ActiveRecord::NullRelation
иActiveRecord::Relation#none
, реализующие паттерн нулевого объекта для класса Relation.Добавлен миграционный хелпер
create_join_table
для создания соединительных таблиц HABTM.Могут быть созданы записи PostgreSQL hstore.
Устаревания
Устарел старый API поиска, основанный на хэше. Это означает, что методы, ранее принимающие "опции поиска", больше так не делают.
Устарели все динамические методы, кроме
find_by_...
иfind_by_...!
устарели. Вот как можно переписать код:* `find_all_by_...` может быть переписан с использованием `where(...)`. * `find_last_by_...` может быть переписан с использованием `where(...).last`. * `scoped_by_...` может быть переписан с использованием `where(...)`. * `find_or_initialize_by_...` может быть переписан с использованием `find_or_initialize_by(...)`. * `find_or_create_by_...` может быть переписан с использованием `find_or_create_by(...)`. * `find_or_create_by_...!` может быть переписан с использованием `find_or_create_by!(...)`.