Заметки о релизе Ruby on Rails 5.1
Ключевые новинки в Rails 5.1:
- Поддержка Yarn
- Опциональная поддержка Webpack
- jQuery больше не является зависимостью по умолчанию
- Системные тесты
- Шифруемые секретные данные
- Параметризованные рассыльщики
- Направленные и вычисляемые маршруты
- Объединение form_for и form_tag в form_with
Эти заметки о релизе покрывают только основные обновления. Чтобы узнать о других обновлениях, различных багфиксах и изменениях, обратитесь к логам изменений или к списку коммитов в главном репозитории Rails на GitHub.
Обновление до Rails 5.1
Если вы обновляете существующее приложение, было бы хорошо иметь перед этим покрытие тестами. Также, до попытки обновиться до Rails 5.1, необходимо сначала обновиться до Rails 5.0 и убедиться, что приложение все еще выполняется так, как нужно. Список вещей, которые нужно выполнить для обновления доступен в руководстве Обновление Rails.
Основные изменения
Поддержка Yarn
Rails 5.1 позволяет управлять зависимостями JavaScript из NPM с помощью Yarn. Это облегчает использование библиотек, таких как React, VueJS и любых других из мира NPM. Поддержка Yarn интегрирована с файлопроводом, поэтому все зависимости будут без проблем работать с приложением Rails 5.1.
Опциональная поддержка Webpack
Приложения Rails можно интегрировать с Webpack, пакетированием ассетов JavaScript, используя новый стандартный гем Webpacker. Укажите флажок --webpack
при генерации новых приложений, чтобы включить интеграцию с Webpack.
Она полностью совместима с файлопроводом, который можно продолжать использовать для картинок, шрифтов, звуков и других ассетов. Можно даже оставить некоторый код JavaScript, управляемый файлопроводом, а остальной код обрабатывать через Webpack. Все это управляется с помощью Yarn, который включен по умолчанию.
jQuery больше не является зависимостью по умолчанию
jQuery требовался по умолчанию в ранних версиях Rails для предоставления особенностей, таких как data-remote
, data-confirm
и других частей, предлагаемых Unobtrusive JavaScript в Rails. Он больше не требуется, так как UJS был переписан с использованием чистого JavaScript. Этот код теперь находится внутри Action View как rails-ujs
.
При необходимости все еще можно использовать jQuery, но он больше не требуется по умолчанию.
Системные тесты
Rails 5.1 имеет встроенную поддержку для написания тестов Capybara в форме системных тестов. Больше не нужно беспокоиться о настройке Capybara и стратегиях очистки базы данных для таких тестов. Rails 5.1 предоставляет обертку для запусков тестов в Chrome с дополнительными особенностями, такими как скриншоты при падении.
Шифруемые секретные данные
Сейчас Rails позволяет управлять секретными данными приложения безопасным образом, наподобие гема sekrets.
Запустите bin/rails secrets:setup
для настройки нового зашифрованного файла с секретными данными. Это также сгенерирует мастер-ключ, который должен храниться вне репозитория. Тогда сами секретные данные могут безопасно добавляться в систему контроля версий в зашифрованной форме.
Секретные данные будут дешифрованы в production с помощью ключа, либо хранящегося в переменной окружения RAILS_MASTER_KEY
, либо в файле с ключом.
Параметризованные рассыльщики
Позволяют определить общие параметры, используемые всеми методами в классе рассыльщика, для переменных экземпляра, заголовков и других общих настроек.
class InvitationsMailer < ApplicationMailer
before_action { @inviter, @invitee = params[:inviter], params[:invitee] }
before_action { @account = params[:inviter].account }
def account_invitation
mail subject: "#{@inviter.name} invited you to their Basecamp (#{@account.name})"
end
end
InvitationsMailer.with(inviter: person_a, invitee: person_b)
.account_invitation.deliver_later
Направленные и вычисляемые маршруты
Rails 5.1 добавляет в DSL роутинга два новых метода, resolve
и direct
. Метод resolve
позволяет настроить полиморфное соответствие моделей.
resource :basket
resolve("Basket") { [:basket] }
<%= form_for @basket do |form| %>
<!-- basket form -->
<% end %>
Это сгенерирует одиночный URL /basket
вместо обычного /baskets/:id
.
Метод direct
позволяет создавать хелперы для произвольного URL.
direct(:homepage) { "http://www.rubyonrails.org" }
>> homepage_url
=> "http://www.rubyonrails.org"
Возвращаемое из блока значение должно быть валидным аргументом для метода url_for
. Поэтому можно передать валидные строковый URL, Hash, Array, экземпляр Active Model или класс Active Model.
direct :commentable do |model|
[ model, anchor: model.dom_id ]
end
direct :main do
{ controller: 'pages', action: 'index', subdomain: 'www' }
end
Объединение form_for и form_tag в form_with
До Rails 5.1 было два интерфейса для обработки форм HTML: form_for
для экземпляров моделей и form_tag
для произвольных URL.
Rails 5.1 объединяет оба этих интерфейса с помощью form_with
и может генерировать теги формы, основанные на URL, скоупах или моделях.
Используя просто URL:
<%= form_with url: posts_path do |form| %>
<%= form.text_field :title %>
<% end %>
<%# Сгенерирует %>
<form action="/posts" method="post" data-remote="true">
<input type="text" name="title">
</form>
Добавление скоупа добавляет префикс для имен полей ввода:
<%= form_with scope: :post, url: posts_path do |form| %>
<%= form.text_field :title %>
<% end %>
<%# Сгенерирует %>
<form action="/posts" method="post" data-remote="true">
<input type="text" name="post[title]">
</form>
URL и скоуп на основе используемой модели:
<%= form_with model: Post.new do |form| %>
<%= form.text_field :title %>
<% end %>
<%# Сгенерирует %>
<form action="/posts" method="post" data-remote="true">
<input type="text" name="post[title]">
</form>
Существующая модель создает форму для обновления и заполняет значения для полей:
<%= form_with model: Post.first do |form| %>
<%= form.text_field :title %>
<% end %>
<%# Сгенерирует %>
<form action="/posts/1" method="post" data-remote="true">
<input type="hidden" name="_method" value="patch">
<input type="text" name="post[title]" value="<the title of the post>">
</form>
Несовместимости
Следующие изменения могут потребовать немедленных действий после обновления.
Транзакционные тесты с несколькими соединениями
Сейчас транзакционные тесты оборачивают все соединения Active Record в транзакции базы данных.
Когда тест порождает дополнительные треды, и эти треды получают соединения с базой данных, то эти соединения теперь обрабатываются по-особенному:
Тредам достается единственное соединение, которое находится посреди управляемой транзакции. Это позволяет убедиться, что все треды видят базу данных в одном и том же состоянии, игнорируя внешнюю транзакцию. Раньше такие дополнительные соединения были неспособны видеть, к примеру, строки фикстур.
Когда тред входит во вложенную транзакцию, он временно получает эксклюзивное использование этого соединения для поддержки изоляции.
Если ваши тесты сейчас полагаются на получение отдельного, внетранзакционного соединения для порождаемого треда, вам необходимо переключиться на более явное управление соединением.
Если ваши тесты порождают треды, и эти треды взаимодействуют, в то же время используя явные соединения с базой данных, то это может вызвать взаимную блокировку (deadlock).
Самым простым способом отказаться от подобного нового поведения является отключение транзакционных тестов для всех тестовых случаев, которые оно затрагивает.
Railties
За подробностями обратитесь к Changelog.
Удалено
Удалена устаревшая
config.static_cache_control
. (commit)Удалена устаревшая
config.serve_static_files
. (commit)Удален устаревший файл
rails/rack/debugger
. (commit)Удалены устаревшие задачи:
rails:update
,rails:template
,rails:template:copy
,rails:update:configs
иrails:update:bin
. (commit)Удалена устаревшая переменная среды
CONTROLLER
для задачиroutes
. (commit)Удалена опция -j (--javascript) для команды
rails new
. (Pull Request)
Значимые изменения
Добавлена общий раздел в
config/secrets.yml
, которая будет загружена для всех сред. (commit)Конфигурационный файл
config/secrets.yml
теперь загружается со всеми ключами в качестве символов. (Pull Request)Убран jquery-rails из стека по умолчанию. rails-ujs, который теперь встроен в Action View, включен в качестве адаптера UJS по умолчанию. (Pull Request)
Добавлена поддержка Yarn для новых приложений с помощью исполняемого файла yarn и package.json. (Pull Request)
В новых приложениях добавлена поддержка Webpack с помощью опции
--webpack
, которая делегируется в гем rails/webpacker. (Pull Request)При генерации нового приложения инициализируется репозиторий Git, если не предоставлена опция
--skip-git
. (Pull Request)Добавлены зашифрованные секретные данные в
config/secrets.yml.enc
. (Pull Request)Отображается имя класса railtie в
rails initializers
. (Pull Request)
Action Cable
За подробностями обратитесь к Changelog.
Значимые изменения
Добавлена поддержка
channel_prefix
к Redis и событийным адаптерам Redis вcable.yml
, чтобы избежать коллизии имен при использовании одного и того же сервера Redis с несколькими приложениями. (Pull Request)Для данных трансляции добавлен хук
ActiveSupport::Notifications
. (Pull Request)
Action Pack
За подробностями обратитесь к Changelog.
Удалено
Удалена поддержка аргументов, не являющихся ключами, в
#process
,#get
,#post
,#patch
,#put
,#delete
и#head
для классовActionDispatch::IntegrationTest
иActionController::TestCase
. (Commit, Commit)Удалены устаревшие
ActionDispatch::Callbacks.to_prepare
иActionDispatch::Callbacks.to_cleanup
. (Commit)Удалены устаревшие методы, относящиеся к фильтрам контроллера. (Commit)
Устарело
- Устарел
config.action_controller.raise_on_unfiltered_parameters
. Он ничего не делает в Rails 5.1. (Commit)
Значимые изменения
Добавлены методы
direct
иresolve
в DSL роутинга. (Pull Request)Добавлен новый класс
ActionDispatch::SystemTestCase
для написания системных тестов вашего приложения. (Pull Request)
Action View
За подробностями обратитесь к Changelog.
Удалено
Удален устаревший
#original_exception
вActionView::Template::Error
. (commit)Удалена неправильно названная опция
encode_special_chars
изstrip_tags
. (Pull Request)
Устарело
- Устаревший обработчик ERB Erubis заменен в пользу Erubi. (Pull Request)
Значимые изменения
Обработчик raw шаблонов (обработчик шаблонов по умолчанию в Rails 5) теперь выводит HTML-безопасные строки. (commit)
Изменены
datetime_field
иdatetime_field_tag
, чтобы они генерировали полеdatetime-local
. (Pull Request)Новый синтаксис в стиле Builder для тегов HTML (
tag.div
,tag.br
и т.д.) (Pull Request)Добавлен
form_with
, объединяющий использованиеform_tag
иform_for
. (Pull Request)Добавлена опция
check_parameters
вcurrent_page?
. (Pull Request)
Action Mailer
За подробностями обратитесь к Changelog.
Значимые изменения
Разрешена установка произвольного типа содержимого, когда включены вложения и тело установлено как inline. (Pull Request)
Разрешена передача lambda в качестве значений в метод
default
. (Commit)Добавлена поддержка параметризованного вызова рассыльщиков для совместного использования предварительных фильтров и значений по умолчанию различными экшнами рассыльщика. (Commit)
Входящие аргументы передаются в экшн рассыльщика в событии
process.action_mailer
в ключеargs
. (Pull Request)
Active Record
За подробностями обратитесь к Changelog.
Удалено
Удалена поддержка одновременной передачи аргументов и блока в
ActiveRecord::QueryMethods#select
. (Commit)Удалены устаревшие скоупы i18n
activerecord.errors.messages.restrict_dependent_destroy.one
иactiverecord.errors.messages.restrict_dependent_destroy.many
. (Commit)Удален устаревший аргумент принудительной перезагрузки для методов чтения одиночной и множественной связи. (Commit)
Удалена устаревшая поддержка передачи столбца в
#quote
. (Commit)Удалены устаревшие аргументы
name
из#tables
. (Commit)Удалено устаревшее поведение
#tables
, и#table_exists?
, которое возвращало таблицы и представления, чтобы теперь возвращало только таблицы, но не представления. (Commit)Удален устаревший аргумент
original_exception
вActiveRecord::StatementInvalid#initialize
иActiveRecord::StatementInvalid#original_exception
. (Commit)Удалена устаревшая поддержка передачи класса в качестве значения в запрос. (Commit)
Удалена устаревшая поддержка запросов с использованием запятых в LIMIT. (Commit)
Удален устаревший параметр
conditions
из#destroy_all
. (Commit)Удален устаревший параметр
conditions
из#delete_all
. (Commit)Удален устаревший метод
#load_schema_for
в пользу#load_schema
. (Commit)Удалена устаревшая конфигурация
#raise_in_transactional_callbacks
. (Commit)Удалена устаревшая конфигурация
#use_transactional_fixtures
. (Commit)
Устарело
Устаревший флажок
error_on_ignored_order_or_limit
заменен в пользуerror_on_ignored_order
. (Commit)Устаревший
sanitize_conditions
заменен в пользуsanitize_sql
. (Pull Request)Устарел
supports_migrations?
в адаптерах соединения. (Pull Request)Устарел
Migrator.schema_migrations_table_name
, вместо него используйтеSchemaMigration.table_name
. (Pull Request)Устарело использование
#quoted_id
в квотировании и приведении типов. (Pull Request)Устарела передача аргумента
default
в#index_name_exists?
. (Pull Request)
Значимые изменения
Изменены первичные ключи по умолчанию на BIGINT. (Pull Request)
Поддержка виртуальных/генерированных столбцов для MySQL 5.7.5+ и MariaDB 5.2.0+. (Commit)
Добавлена поддержка лимитов в обработке пакетами. (Commit)
Транзакционные тесты теперь оборачивают все соединения Active Record в транзакцию базы данных. (Pull Request)
По умолчанию опускаются комментарии в выводе команды
mysqldump
. (Pull Request)Починен
ActiveRecord::Relation#count
, чтобы использовалсяEnumerable#count
из Ruby для подсчета записей, когда передан блок, вместо игнорирования переданного блока. (Pull Request)Передача флажка
"-v ON_ERROR_STOP=1"
командеpsql
не подавляет ошибки SQL. (Pull Request)Добавлен
ActiveRecord::Base.connection_pool.stat
. (Pull Request)Наследование непосредственно от
ActiveRecord::Migration
вызывает ошибку. Необходимо указывать версию Rails, для которой была написана миграция. (Commit)Вызывается ошибка, когда у связи
through
имеется избыточное имя противоположной связи. (Commit)
Active Model
За подробностями обратитесь к Changelog.
Удалено
Удалены устаревшие методы в
ActiveModel::Errors
. (commit)Удалена устаревшая опция
:tokenizer
в валидаторе длины. (commit)Удалено устаревшее поведение, прерывающее колбэки, когда возвращаемое значение равно false. (commit)
Значимые изменения
- Оригинальная строка, назначенная атрибуту модели, больше не замораживается некорректно. (Pull Request)
Active Job
За подробностями обратитесь к Changelog.
Удалено
Удалена устаревшая поддержка передачи класса адаптера в
.queue_adapter
. (commit)Удален устаревший
#original_exception
вActiveJob::DeserializationError
. (commit)
Значимые изменения
Добавлена декларативная обработка исключений с помощью
ActiveJob::Base.retry_on
иActiveJob::Base.discard_on
. (Pull Request)После того, как все попытки провалятся, передается экземпляр задания, поэтому у вас будет доступ к таким вещам, как
job.arguments
, для реализации собственной логики. (commit)
Active Support
За подробностями обратитесь к Changelog.
Удалено
Удален класс
ActiveSupport::Concurrency::Latch
. (Commit)Удалена
halt_callback_chains_on_return_false
. (Commit)Удалено устаревшее поведение, прерывающее колбэки, когда возвращаемое значение равно false. (Commit)
Устарело
Верхнеуровневый класс
HashWithIndifferentAccess
устарел в пользуActiveSupport::HashWithIndifferentAccess
. (Pull Request)Устарела передача строк в опции условий
:if
и:unless
для методовset_callback
иskip_callback
. (Commit)
Значимые изменения
Починен парсинг продолжительности и перемещения во времени, теперь он более последователен при смене DST. (Commit, Pull Request)
Unicode обновлен до версии 9.0.0. (Pull Request)
Добавлены Duration#before и #after в качестве псевдонимов для #ago и #since. (Pull Request)
Добавлен
Module#delegate_missing_to
для делегирования вызовов метода, не определенного для текущего объекта, на прокси-объект. (Pull Request)Добавлен
Date#all_day
, возвращающий интервал, представляющий целый день для текущих даты и времени. (Pull Request)Представлены методы
assert_changes
иassert_no_changes
для тестов. (Pull Request)Методы
travel
иtravel_to
теперь вызывают ошибку на вложенных вызовах. (Pull Request)Обновлен
DateTime#change
для поддержки usec и nsec. (Pull Request)
Благодарности
Взгляните на полный список контрибьюторов Rails, на людей, которые потратили много часов, сделав Rails стабильнее и надёжнее. Спасибо им всем.