Заметки о релизе Ruby on Rails 8.1
Ключевые новинки в Rails 8.1:
Ключевые новинки в Rails 8.1:
- Продолжения Active Job (Continuations).
- Структурированная отчётность о событиях (Structured Event Reporting).
- Локальный CI.
- Рендеринг Markdown.
- Получение учётных данных из командной строки.
- Устаревшие связи (Deprecated Associations).
- Развёртывания Kamal без реестра (Registry-Free).
Эти заметки о релизе покрывают только основные изменения. Чтобы узнать о других обновлениях, различных исправлениях программных ошибок и изменениях, обратитесь к логам изменений или к списку коммитов в главном репозитории Rails на GitHub.
Апгрейд до Rails 8.1
Прежде чем апгрейднуть существующее приложение, было бы хорошо иметь перед этим покрытие тестами. Также, до попытки обновиться до Rails 8.1, необходимо сначала произвести апгрейд до Rails 8.0 и убедиться, что приложение все еще выполняется так, как нужно. Список вещей, которые нужно выполнить для апгрейда доступен в руководстве Апгрейд Ruby on Rails.
Основные особенности
Продолжения Active Job
Длительно выполняющиеся задания теперь можно разбивать на отдельные шаги, что позволяет после перезапуска продолжить выполнение с последнего завершённого шага, а не с самого начала. Это особенно полезно при развёртываниях с Kamal, который по умолчанию даёт контейнерам с выполняющимися заданиями всего тридцать секунд на завершение работы.
Пример:
class ProcessImportJob < ApplicationJob
include ActiveJob::Continuable
def perform(import_id)
@import = Import.find(import_id)
# формат блока
step :initialize do
@import.initialize
end
# шаг с курсором; курсор сохраняется при прерывании задания
step :process do |step|
@import.records.find_each(start: step.cursor) do |record|
record.process
step.advance! from: record.id
end
end
# формат метода
step :finalize
end
private
def finalize
@import.finalize
end
endСтруктурированная отчётность о событиях
Стандартный логгер в Rails хорош для чтения человеком, но менее удобен для последующей обработки. Новый Event Reporter предоставляет унифицированный интерфейс для создания структурированных событий в Rails-приложениях:
Rails.event.notify("user.signup", user_id: 123, email: "user@example.com")Он поддерживает добавление тегов к событиям:
Rails.event.tagged("graphql") do
# Событие будет содержать теги: { graphql: true }
Rails.event.notify("user.signup", user_id: 123, email: "user@example.com")
endА также контекст:
# Все события будут содержать контекст: {request_id: "abc123", shop_id: 456}
Rails.event.set_context(request_id: "abc123", shop_id: 456)События отправляются подписчикам. Приложения регистрируют подписчиков, чтобы управлять сериализацией и отправкой событий. Подписчики должны реализовывать метод #emit, который принимает хэш события:
class LogSubscriber
def emit(event)
payload = event[:payload].map { |key, value| "#{key}=#{value}" }.join(" ")
source_location = event[:source_location]
log = "[#{event[:name]}] #{payload} at #{source_location[:filepath]}:#{source_location[:lineno]}"
Rails.logger.info(log)
end
endЛокальный CI
Машины разработчиков стали невероятно быстрыми и обзавелись множеством ядер, что делает их отличными площадками для локального запуска даже относительно крупных тестовых наборов.
Это делает отказ от облачной CI-инфраструктуры не просто возможным, но и желательным для многих небольших и средних приложений. Поэтому Rails добавил стандартный DSL для описания CI, который определяется в файле config/ci.rb и запускается командой bin/ci. Он выглядит так:
CI.run do
step "Setup", "bin/setup --skip-server"
step "Style: Ruby", "bin/rubocop"
step "Security: Gem audit", "bin/bundler-audit"
step "Security: Importmap vulnerability audit", "bin/importmap audit"
step "Security: Brakeman code analysis", "bin/brakeman --quiet --no-pager --exit-on-warn --exit-on-error"
step "Tests: Rails", "bin/rails test"
step "Tests: Seeds", "env RAILS_ENV=test bin/rails db:seed:replant"
# Требует наличия `gh` CLI и `gh extension install basecamp/gh-signoff`.
if success?
step "Signoff: All systems go. Ready for merge and deploy.", "gh signoff"
else
failure "Signoff: CI failed. Do not merge or deploy.", "Fix the issues and try again."
end
endОпциональная интеграция с gh гарантирует, что PR-ы для слияния обязательно должны быть подтверждены успешным прогоном CI.
Рендеринг Markdown
Markdown стал общим языком ИИ, и Rails поддержал этот тренд, упростив ответы на запросы в формате markdown и их прямой рендеринг:
class Page
def to_markdown
body
end
end
class PagesController < ActionController::Base
def show
@page = Page.find(params[:id])
respond_to do |format|
format.html
format.md { render markdown: @page }
end
end
endПолучение учётных данных из командной строки
Kamal теперь может легко получать свои секреты из зашифрованного хранилища Rails credentials для развёртываний. Это делает его низкоуровневой альтернативой внешним хранилищам секретов, для работы которой требуется только мастер-ключ:
# .kamal/secrets
KAMAL_REGISTRY_PASSWORD=$(rails credentials:fetch kamal.registry_password)Устаревшие связи
Связи Active Record теперь можно помечать как устаревшие:
class Author < ApplicationRecord
has_many :posts, deprecated: true
endПосле этого использование связи posts будет сообщаться. Это включает явные вызовы API, такие как
author.posts
author.posts = ...и другие, а также косвенное использование, например
author.preload(:posts)использование через nested attributes и прочее.
Поддерживаются три режима оповещения (:warn, :raise и :notify); трассировку стека можно включить или выключить, но местоположение зарегистрированного использования вы всегда получите независимо от настроек. По умолчанию используется режим :warn с выключенной трассировкой стека.
Развёртывания Kamal без реестра
Kamal больше не нуждается в удалённом реестре, таком как Docker Hub или GHCR, для простых развёртываний. По умолчанию Kamal 2.8 теперь использует локальный реестр для простых развёртываний. Для крупномасштабных развёртываний удалённый реестр всё ещё понадобится, но это упрощает старт и позволяет быстрее увидеть своё первое «Hello World» развёртывание в действии.
Railties
За подробностями обратитесь к Changelog.
Удалено
-
Удалён устаревший файл
rails/console/methods.rb. -
Удалена устаревшая команда
bin/rake stats. -
Удалена устаревшая константа
STATS_DIRECTORIES.
Устарело
Значимые изменения
Action Cable
За подробностями обратитесь к Changelog.
Удалено
Устарело
Значимые изменения
Action Pack
За подробностями обратитесь к Changelog.
Удалено
-
Удалена устаревшая поддержка пропуска ведущих скобок в именах параметров в парсере параметров.
До:
ActionDispatch::ParamBuilder.from_query_string("[foo]=bar") # => { "foo" => "bar" } ActionDispatch::ParamBuilder.from_query_string("[foo][bar]=baz") # => { "foo" => { "bar" => "baz" } }После:
ActionDispatch::ParamBuilder.from_query_string("[foo]=bar") # => { "[foo]" => "bar" } ActionDispatch::ParamBuilder.from_query_string("[foo][bar]=baz") # => { "[foo]" => { "bar" => "baz" } } -
Удалена устаревшая поддержка использования точки с запятой в качестве разделителя строки запроса.
До:
ActionDispatch::QueryParser.each_pair("foo=bar;baz=quux").to_a # => [["foo", "bar"], ["baz", "quux"]]После:
ActionDispatch::QueryParser.each_pair("foo=bar;baz=quux").to_a # => [["foo", "bar;baz=quux"]] -
Удалена устаревшая поддержка указания нескольких путей для одного маршрута.
Устарело
- Устарел
Rails.application.config.action_dispatch.ignore_leading_brackets.
Значимые изменения
- Редиректы в режиме разработки теперь подробные для новых Rails-приложений. Чтобы включить их в существующем приложении, добавьте
config.action_dispatch.verbose_redirect_logs = trueв файлconfig/development.rb.
Action View
За подробностями обратитесь к Changelog.
Удалено
Устарело
- Устарели вызовы
renderс объектами:renderable, у которых#render_inотвечает без ключевых аргументов.
Значимые изменения
Action Mailer
За подробностями обратитесь к Changelog.
Удалено
Устарело
Значимые изменения
Active Record
За подробностями обратитесь к Changelog.
Удалено
-
Удалена устаревшая опция
:retriesдля адаптера SQLite3. -
Удалены устаревшие методы колонок
:unsigned_floatи:unsigned_decimalдля MySQL.
Устарело
-
Устарело использование методов поиска, зависящих от порядка (например,
#first), безorder. -
Устарел
ActiveRecord::Base.signed_id_verifier_secretв пользуRails.application.message_verifiers(илиModel.signed_id_verifier, если секрет специфичен для модели). -
Устарело использование
insert_all/upsert_allс непомещёнными в БД (unpersisted) записями в связях. -
Устарело использование
WITH,WITH RECURSIVEиDISTINCTсupdate_all.
Значимые изменения
- Столбцы таблиц внутри
schema.rbтеперь сортируются по алфавиту.
Active Storage
За подробностями обратитесь к Changelog.
Удалено
- Удалён устаревший сервис хранилища
:azure.
Устарело
Значимые изменения
Active Model
За подробностями обратитесь к Changelog.
Удалено
Устарело
Значимые изменения
Active Support
За подробностями обратитесь к Changelog.
Удалено
-
Удалена устаревшая передача объекта Time в
Time#since. -
Удалён устаревший метод
Benchmark.ms. Теперь он определён в гемеbenchmark. -
Удалено устаревшее сложение экземпляров
TimeсActiveSupport::TimeWithZone. -
Удалена устаревшая поддержка
to_time, сохраняющая системное локальное время. Теперь он всегда сохраняет временную зону получателя.
Устарело
-
Устарел
config.active_support.to_time_preserves_timezone. -
Устарели
String#mb_charsиActiveSupport::Multibyte::Chars. -
Устарел
ActiveSupport::Configurable.
Значимые изменения
Active Job
За подробностями обратитесь к Changelog.
Удалено
-
Удалена поддержка установки
ActiveJob::Base.enqueue_after_transaction_commitв значения:never,:alwaysи:default. -
Удалён устаревший
Rails.application.config.active_job.enqueue_after_transaction_commit. -
Удалён устаревший внутренний адаптер
SuckerPunchв пользу адаптера, включённого в гемsucker_punch.
Устарело
-
Пользовательские сериализаторы Active Job должны иметь публичный метод
#klass. -
Устарел встроенный адаптер
sidekiq(теперь предоставляется гемомsidekiq).
Значимые изменения
Action Text
За подробностями обратитесь к Changelog.
Удалено
Устарело
-
Устарел класс
ActionText::TrixAttachment. -
Устарел модуль
ActionText::Attachments::TrixConversion. -
Устарел
ActionText::Attachable#to_trix_content_attachment_partial_path. Переопределяйтеto_editor_content_attachment_partial_pathвместо него. -
Устарел
ActionText::RichText#to_trix_html. -
Устарел
ActionText::Content#to_trix_html.
Значимые изменения
Action Mailbox
За подробностями обратитесь к Changelog.
Удалено
Устарело
Значимые изменения
Ruby on Rails Guides
За подробностями обратитесь к Changelog.
Значимые изменения
Credits
Взгляните на полный список контрибьюторов Rails, на людей, которые потратили много часов, сделав Rails стабильнее и надёжнее. Спасибо им всем.