Ключевые новинки в Rails 5.0

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

1. Основные изменения

1.1. Action Cable

Action Cable — это новый фреймворк в Rails 5. Он с легкостью интегрирует WebSockets с остальными частями вашего приложения Rails.

Action Cable позволяет писать функционал реального времени на Ruby в стиле и формате остальной части приложения Rails, в то же время являясь производительным и масштабируемым. Он представляет полный стек, включая клиентский фреймворк на JavaScript и серверный фреймворк на Ruby. Вы получаете доступ к моделям, написанным с помощью Active Record или другой ORM.

1.2. Rails API

дополняется…

1.3. API атрибутов Active Record

Определяет в модели тип с атрибутом. Это позволит при необходимости переопределить тип существующих атрибутов. Это позволяет контролировать, как значения конвертируются в и из SQL при присвоении модели. Это также изменяет поведение значений, переданных в ActiveRecord::Base.where, что позволяет использовать наши объекты предметной области в большей части Active Record не полагаясь на особенности реализации или monkey patching.

Некоторые из вещей, которые можно достичь с помощью этого:

# db/schema.rb
create_table :store_listings, force: true do |t|
  t.decimal :price_in_cents
  t.string :my_string, default: "original default"
end
 
# app/models/store_listing.rb
class StoreListing < ActiveRecord::Base
end
 
store_listing = StoreListing.new(price_in_cents: '10.1')
 
# before
store_listing.price_in_cents # => BigDecimal.new(10.1)
StoreListing.new.my_string # => "original default"
 
class StoreListing < ActiveRecord::Base
  attribute :price_in_cents, :integer # настраиваемый тип
  attribute :my_string, :string, default: "new default" # значение по умаолчанию
  attribute :my_default_proc, :datetime, default: -> { Time.now } # значение по умолчанию
  attribute :field_without_db_column, :integer, array: true
end
 
# after
store_listing.price_in_cents # => 10
StoreListing.new.my_string # => "new default"
StoreListing.new.my_default_proc # => 2015-05-30 11:04:48 -0600
model = StoreListing.new(field_without_db_column: ["1", "2", "3"])
model.attributes #=> {field_without_db_column: [1, 2, 3]}

Создание собственных типов:

Можно определить свои собственные типы, но они должны отвечать на методы для определенного типа значения. Метод +deserialize+ или +cast+ будет вызван на вашем объекте типа с необработанными данными из базы данных или от контроллера. Это полезно, к примеру, при осуществлении пользовательских преобразований, таких как данные Money.

Запросы:

При вызове ActiveRecord::Base.where, он будет использовать тип, определенный классом модели, для конвертации значения в SQL, вызвав +serialize+ на вашем объекте типа.

Это дает объектам способность указывать, как конвертировать значения при выполнении запросов SQL.

Отслеживание изменений (Dirty Tracking):

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

Подробности смотрите в его документации.

1.4. Test Runner

дополняется…

2. Railties

За подробностями обратитесь к Changelog.

2.1. Удалено

Удалена поддержка debugger, используйте вместо него byebug. debugger больше не поддерживается Ruby 2.2.

Удалены устаревшие задачи test:all и test:all:db.

Удален устаревший Rails::Rack::LogTailer.

Удалена устаревшая константа RAILS_CACHE.

Удалена устаревшая настройка serve_static_assets.

Удалены задачи для документации doc:app, doc:rails и doc:guides.

Из стека по умолчанию удалена промежуточная программа Rack::ContentLength.

2.2. Устарело

Устарела config.static_cache_control в пользу config.public_file_server.headers.

Устарела config.serve_static_files в пользу config.public_file_server.enabled.

Устарели задачи в пространстве имен rails в пользу пространства имен app. (например, задачи rails:update и rails:template переименованы в app:update и app:template.)

2.3. Значимые изменения

Добавлен Rails test runner bin/rails test.

Вновь сгенерированные приложения и плагины получают README.md в формате Markdown.

Добавлена задача bin/rails restart для перезапуска вашего приложения Rails, изменяя время tmp/restart.txt.

Добавлена задача bin/rails initializers, выводящая все определенные инициализаторы в том порядке, в котором они вызываются Rails.

Добавлена bin/rails dev:cache для включения или отключения кэширования в режиме разработки.

Добавлен скрипт bin/update для автоматического обновления среды development.

Проксируются задачи Rake с помощью bin/rails.

Новые приложения генерируются с включенным монитором событийной файловой системы на Linux и Mac OS X. Эта особенность может быть отключена, передав --skip-listen в генератор.

Генерация приложений с опцией вывода лога в STDOUT в production с помощью переменной среды RAILS_LOG_TO_STDOUT>.

Для новых приложений включен HSTS с заголовком IncludeSudomains.

Генератор приложения создает новый файл config/spring.rb, который сообщает Spring наблюдать за дополнительными распространенными файлами.

Добавлена --skip-action-mailer, чтобы пропустить Action Mailer при генерации нового приложения.

Убрана директория tmp/sessions и задача очистки rake, связанная с ней.

Изменен _form.html.erb, генерируемый скаффолдом, чтобы использовались локальные переменные.

3. Action Pack

За подробностями обратитесь к Changelog.

3.1. Удалено

Удален ActionDispatch::Request::Utils.deep_munge.

Удален ActionController::HideActions.

Удалены методы respond_to и respond_with>, этот функционал был извлечен в гем responders.

Удалены устаревшие файлы тестовых утверждений.

Удалено устаревшее использование строковых ключей в хелперах путей.

Удалена устаревшая опция only_path в хелперах *_path.

Удален устаревший NamedRouteCollection#helpers.

Удалена устаревшая поддержка определения маршрутов с помощью опции :to, не содержащей #.

Удален устаревший ActionDispatch::Response#to_ary.

Удален устаревший ActionDispatch::Request#deep_munge.

Удален устаревший ActionDispatch::Http::Parameters#symbolized_path_parameters.

Удалена устаревшая опция use_route в тестах контроллеров.

Удалены assigns и assert_template. Оба метода были извлечены в гем rails-controller-testing.

3.2. Устарело

Устарели все колбэки *_filter в пользу колбэков *_action.

Устарели интеграционные методы тестирования *_via_redirect. Используйте вручную follow_redirect! после вызова запроса для того же поведения.

Устарел AbstractController#skip_action_callback в пользу отдельных методов skip_callback.

Устарела опция :nothing для метода render.

Устарела передача первого параметра как Hash и код статуса по умолчанию для метода head.

Устарело использование строк или символов для имен классов промежуточных программ. Используйте вместо них имена классов.

Устарел доступ к типам mime с помощью констант (т.е. Mime::HTML). Вместо них используйте оператор индексирования с символом (т.е. Mime[:html]).

Устарел redirect_to :back в пользу redirect_back, который принимает аргумент fallback_location, устраняющий возможность RedirectBackError.

В ActionDispatch::IntegrationTest и ActionController::TestCase устарели позиционные аргументы в пользу аргументов с ключевым словом.

Устарели параметры пути :controller и :action.

3.3. Значимые изменения

Добавлен ActionController::Renderer для рендера произвольных шаблонов вне экшнов контроллера.

Произошел переход на синтаксис с ключевыми аргументами в методах запроса HTTP ActionController::TestCase и ActionDispatch::Integration.

В Action Controller добавлен http_cache_forever, таким образом можно кэшировать отклик, который никогда не устаревает.

Предоставлен более дружелюбный доступ к вариантам запроса.

Для экшнов без соответствующих шаблонов рендерится head :no_content вместо вызова ошибки.

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

Добавлена поддержка для чистых API-приложений. Добавлен ActionController::API в качестве замены ActionController::Base для такого типа приложений.

ActionController::Parameters больше не наследуется от HashWithIndifferentAccess.

Упрощена настройка config.force_ssl и config.ssl_options, они сделаны менее опасными для пробы и более простыми для отключения.

Добавлена возможность возврата произвольных заголовков в ActionDispatch::Static.

Изменено значение по умолчанию для опции prepend метода protect_from_forgery на false.

ActionController::TestCase будет перемещен в отдельный гем в Rails 5.1. Вместо него используйте ActionDispatch::IntegrationTest.

Rails будет генерировать только “слабые”, в отличие от сильных ETag.

Экшны контроллера без явного вызова render и без соответствующих шаблонов будут неявно рендерить head :no_content вместо вызова ошибки.

Добавлена опция для CSRF токенов для отдельной формы.

Добавлены кодировка запроса и парсинг отклика в интеграционные тесты.

Обновлены политики рендеринга по умолчанию, когда экшн контроллера не указывает явно отклик.

Добавлен ActionController#helpers для получения доступа к контексту вьюхи на уровне контроллера.

Показанные сообщения flash убираются перед сохранением в сессию.

4. Action View

За подробностями обратитесь к Changelog.

4.1. Удалено

Уделен устаревший AbstractController::Base::parent_prefixes.

Удален ActionView::Helpers::RecordTagHelper, этот функционал был извлечен в гем record_tag_helper.

Убрана опция :rescue_format для хелпера translate, так как она больше не поддерживается i18n.

4.2. Устарело

Устарели хелперы datetime_field и datetime_field_tag. Тип ввода datetime был убран из спецификации HTML. Вместо них можно использовать datetime_local_field и datetime_local_field_tag. 5.3. Значимые изменения

Изменен обработчик шаблонов по умолчанию с ERB на Raw.

Рендеринг коллекций может кэшировать и извлекать несколько партиалов за раз.

Добавлено универсальное сопоставление для явных зависимостей.

disable_with сделано поведением по умолчанию для тегов submit. Отключает кнопку при отправке, чтобы предотвратить двойную отправку.

Имя шаблона партиала больше не обязано быть валидным идентификатором Ruby.

5. Action Mailer

За подробностями обратитесь к Changelog.

5.1. Удалено

Удалены устаревшие хелперы *_path во вьюхах email.

Удалены устаревшие методы deliver и deliver!.

5.2. Значимые изменения

Поиск шаблонов теперь учитывает локаль по умолчанию и фолбэки I18n.

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

Добавлены assert_enqueued_emails и assert_no_enqueued_emails.

Добавлена настройка config.action_mailer.deliver_later_queue_name для установления имени очереди рассыльщика.

Добавлена поддержка кэширования фрагмента во вьюхах Action Mailer. Добавлена новая конфигурационная опция config.action_mailer.perform_caching для определения, должны ли ваши шаблоны осуществлять кэширование или нет.

6. Active Record

За подробностями обратитесь к Changelog.

6.1. Удалено

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

Удален устаревший ActiveRecord::Tasks::DatabaseTasks#load_schema. Этот метод был заменен ActiveRecord::Tasks::DatabaseTasks#load_schema_for.

Удален устаревший serialized_attributes.

Удалены устаревшие автоматические кэши счетчиков на has_many :through.

Удален устаревший sanitize_sql_hash_for_conditions.

Удален устаревший Reflection#source_macro.

Удалены устаревшие symbolized_base_class и symbolized_sti_name.

Удалены устаревшие ActiveRecord::Base.disable_implicit_join_references=.

Удален устаревший доступ к спецификации соединения с помощью строкового метода доступа.

Удалена устаревшая поддержка предварительной загрузки связей, зависимых от экземпляра.

Удалена устаревшая поддержка интервалов PostgreSQL с исключенной нижней границей.

Удалено предупреждение об устаревании при при изменении relation с кэшированным Arel. Вместо этого вызывается ошибка ImmutableRelation.

Из ядра удален ActiveRecord::Serialization::XmlSerializer. Эта особенность была извлечена в гем activemodel-serializers-xml.

Из ядра удалена поддержка старой версии адаптера баз данных mysql. Пока что он будет существовать в отдельном геме, но большинство пользователей должны просто использовать mysql2.

Удалена поддержка гема protected_attributes.

Удалена поддержка для PostgreSQL версии ниже 9.1.

Удалена поддержка гема activerecord-deprecated_finders.

6.2. Устарело

Устарела передача класса в качестве значения запроса. Вместо этого нужно передавать строки.

Устарел возврат false в качестве способа прервать цепочку колбэков Active Record. Рекомендуемый способ throw(:abort).

Устарел ActiveRecord::Base.errors_in_transactional_callbacks=.

Устарел Relation#uniq, вместо него используйте Relation#distinct.

Устарел тип PostgreSQL :point в пользу нового, возвращающего объекты Point вместо Array

Устарело принуждение к перезагрузке связи с помощью передачи истинного аргумента в метод связи.

Устарели ключи для ошибок связи restrict_dependent_destroy в пользу новых имен ключей.

Синхронизировано поведение #tables.

Устарели SchemaCache#tables, SchemaCache#table_exists? и SchemaCache#clear_table_cache! в пользу их новых дубликатов data_source.

Устарел connection.tables в адаптерах SQLite3 и MySQL.

Устарела передача аргументов в #tables - метод #tables в некоторых адаптерах (mysql2, sqlite3) мог возвращать и таблицы, и представления, в то время как другие (postgresql) просто возвращали таблицы. Чтобы сделать их поведение согласующимся, в будущем #tables будет возвращать только таблицы.

Устарел table_exists? - метод #table_exists? мог проверять и таблицы, и представления. Чтобы сделать его поведение согласующимся с #tables, в будущем #table_exists? будет проверять только таблицы.

Устарела отправка аргумента offset в find_nth. Вместо этого используйте метод offset на relation.

Устарели {insert|update|delete}_sql в DatabaseStatements. Вместо этого используйте публичные методы {insert|update|delete}.

Устарел use_transactional_fixtures в пользу use_transactional_tests для большей ясности.

6.3. Значимые изменения

Добавлена опция foreign_key в references во время создания таблицы.

Новый API атрибутов.

Добавлена опция :_prefix/:_suffix в определении enum.

Добавлен #cache_key в ActiveRecord::Relation.

Изменено значение по умолчанию null для timestamps на false.

Добавлен ActiveRecord::SecureToken, чтобы инкапсулировать генерацию уникальных токенов для атрибутов модели с помощью SecureRandom.

Добавлена опция :if_exists для drop_table.

Добавлен ActiveRecord::Base#accessed_fields, который может быть использован, чтобы быстро просмотреть, какие поля были прочитаны из модели, когда вы выбираете только те данные из базы данных, которые вам нужны.

Добавлен метод #or на ActiveRecord::Relation, позволяющий использование оператора OR в сочетании с выражениями WHERE или HAVING.

Добавлена опция :time для #touch.

Добавлен ActiveRecord::Base.suppress предотвращающий получатель от сохранения в заданном блоке.

belongs_to по умолчанию теперь вызывает ошибку валидации, если связь не существует. Это можно отключить для конкретной связи с помощью optional: true. Также устарела опция required в пользу optional для belongs_to.

Добавлен config.active_record.dump_schemas для настройки поведения db:structure:dump.

Добавлена опция config.active_record.warn_on_records_fetched_greater_than.

Добавлена поддержка нативного типа данных JSON в MySQL.

Добавлена поддержка для параллельного удаления индексов в PostgreSQL.

Добавлены методы #views и #view_exists? на адаптерах соединений.

Добавлен ActiveRecord::Base.ignored_columns, чтобы сделать некоторые столбцы невидимыми из Active Record.

Добавлены connection.data_sources и connection.data_source_exists?. Эти методы определяют, какие relation могут быть использованы для создание моделей Active Record (обычно таблицы и представления).

В файлах фикстур можно указать класс модели в самом файле YAML.

Добавлена возможность по умолчанию указать uuid в качестве первичного ключа при генерации миграций базы данных.

Добавлены ActiveRecord::Relation#left_joins и ActiveRecord::Relation#left_outer_joins.

Добавлены колбэки after_{create,update,delete}_commit.

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

ApplicationRecord - это новый суперкласс для всех моделей приложения, по аналогии с контроллерами приложения, являющимися подклассами ApplicationController вместо ActionController::Base. Это дает возможность приложениям иметь единое место для настройки специфичного для приложения поведения модели.

Добавлены методы ActiveRecord #second_to_last и #third_to_last.

Добавлена возможность аннотации объектов базы данных (таблиц, столбцов, индексов) комментариями, хранимыми в метаданных базы данных для PostgreSQL & MySQL.

Добавлена поддержка подготовленных выражений (prepared statements) для адаптера mysql2, для mysql2 0.4.4+. Раньше это поддерживалось только устаревшим адаптером mysql. Чтобы включить, установите prepared_statements: true в config/database.yml.

Добавлена возможность вызвать ActionRecord::Relation#update на реляционных объектах, который запустит валидации на колбэках на всех объектах в реляции.

Добавлена опция :touch в метод save, таким образом, записи могут быть сохранены без обновления временных меток.

Добавлена поддержка индексов по выражениям (expression indexes) и классов оператора (operator classes) для PostgreSQL.

Добавлена опция :index_errors для добавления индексов к ошибкам вложенных атрибутов.

7. Active Model

За подробностями обратитесь к Changelog.

7.1. Удалено

Удалены устаревшие ActiveModel::Dirty#reset_#{attribute} и ActiveModel::Dirty#reset_changes.

Удалена сериализация XML. Эта особенность была извлечена в гем activemodel-serializers-xml.

Удален модуль ActionController::ModelNaming.

7.2. Устарело

Устарел возврат false в качестве способа прервать цепочку колбэков Active Model и ActiveModel::Validations. Рекомендуемый способ throw(:abort).

Устарели методы ActiveModel::Errors#get, ActiveModel::Errors#set и ActiveModel::Errors#[]=, имеющие противоречивое поведение.

Устарела опция :tokenizer для validates_length_of в пользу чистого Ruby.

Устарели ActiveModel::Errors#add_on_empty и ActiveModel::Errors#add_on_blank без замены.

7.3. Значимые изменения

Добавлен ActiveModel::Errors#details для определения, какие валидаторы провалились.

Извлечен ActiveRecord::AttributeAssignment в ActiveModel::AttributeAssignment, позволяя его использование в любом объекте в качестве включаемого модуля.

Добавлены ActiveModel::Dirty#[attr_name]_previously_changed? и ActiveModel::Dirty#[attr_name]_previous_change для улучшения доступа в записанные изменения после того, как модель была сохранена.

Валидация нескольких контекстов за раз в valid? и invalid?.

8. Active Job

За подробностями обратитесь к Changelog.

8.1. Значимые изменения

ActiveJob::Base.deserialize делегируется в класс задачи. Это позволяет задачам присоединить произвольные метаданные при сериализации и прочитать их при выполнении.

Добавлена возможность настроить адаптер очереди для каждой задачи без взаимного влияния друг на друга.

Сгенерированная задача теперь по умолчанию наследуется от app/jobs/application_job.rb.

Позволяет DelayedJob, Sidekiq, qu, que и queue_classic возвращать ActiveJob::Base id задачи как provider_job_id.

Реализован простой процессор AsyncJob и связанный AsyncAdapter, который складывает задачи в пул тредов concurrent-ruby.

Изменен адаптер по умолчанию со встроенного на асинхронный. Это лучше по умолчанию, так как тогда тесты не будут ошибочно проходить, полагаясь на поведение, проходящее синхронно.

9. Active Support

За подробностями обратитесь к Changelog.

9.1. Удалено

Удален устаревший ActiveSupport::JSON::Encoding::CircularReferenceError.

Удалены устаревшие методы ActiveSupport::JSON::Encoding.encode_big_decimal_as_string= и ActiveSupport::JSON::Encoding.encode_big_decimal_as_string.

Удален устаревший ActiveSupport::SafeBuffer#prepend.

Удалены устаревшие методы из Kernel. silence_stderr, silence_stream, capture и quietly.

Удален устаревший файл active_support/core_ext/big_decimal/yaml_conversions.

Удалены устаревшие методы ActiveSupport::Cache::Store.instrument и ActiveSupport::Cache::Store.instrument=.

Удален устаревший Class#superclass_delegating_accessor. Вместо него используйте Class#class_attribute.

Удален устаревший ThreadSafe::Cache. Вместо него используйте Concurrent::Map.

Удален Object#itself, так как он реализован в Ruby 2.2.

9.2. Устарело

Устарел MissingSourceFile в пользу LoadError.

Устарел alias_method_chain в пользу Module#prepend, представленного в Ruby 2.0.

Устарел ActiveSupport::Concurrency::Latch в пользу Concurrent::CountDownLatch из concurrent-ruby.

Устарела опция :prefix для number_to_human_size без замены.

Устарел Module#qualified_const_ в пользу встроенных методов Module#const_.

Устарела передача строки для определения колбэков.

Устарели ActiveSupport::Cache::Store#namespaced_key, ActiveSupport::Cache::MemCachedStore#escape_key и ActiveSupport::Cache::FileStore#key_file_path. Вместо них используйте normalize_key.

Устарел ActiveSupport::Cache::LocaleCache#set_cache_value в пользу write_cache_value.

Устарела передача аргументов в assert_nothing_raised.

Устарел Module.local_constants в пользу Module.constants(false).

9.3. Значимые изменения

Добавлены методы #verified и #valid_message? в ActiveSupport::MessageVerifier.

Изменен способ, которым прерываются цепочки колбэков. Теперь предпочтительный метод прерывания цепочки колбэков – явный throw(:abort).

Новая конфигурационная опция config.active_support.halt_callback_chains_on_return_false для определения, могут ли колбэки ActiveRecord, ActiveModel и ActiveModel::Validations быть прерваны, возвращая false в колбэке 'before'.

Изменена сортировка тестов по умолчанию с :sorted на :random.

Добавлены методы #on_weekend?, #on_weekday?, #next_weekday, #prev_weekday в Date, Time и DateTime.

Добавлена опция same_time для #next_week и #prev_week в Date, Time и DateTime.

Добавлены аналоги #prev_day и #next_day для #yesterday и #tomorrow в Date, Time и DateTime.

Добавлен SecureRandom.base58 для генерации случайных строк base58.

Добавлен file_fixture в ActiveSupport::TestCase. Он представляет простой механизм для доступа к файлам с примерами в ваших тестовых случаях.

Добавлен #without в Enumerable и Array, возвращающий копию enumerable без определенных элементов.

Добавлены ActiveSupport::ArrayInquirer и Array#inquiry.

Добавлен ActiveSupport::TimeZone#strptime, позволяющий парсить время, как будто из заданной временной зоны.

Добавлены предикатные методы Integer#positive? и Integer#negative? в духе Integer#zero?.

Добавлены восклицательные версии методов доступа в ActiveSupport::OrderedOptions, вызывающие KeyError, если значение .blank?.

Добавлен Time.days_in_year, возвращающий количество дней в заданном году, или в текущем году, если не указан аргумент.

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

Добавлен набор методов thread_m/cattr_accessor/reader/writer для объявления переменных класса и модуля, существующих отдельно для каждого треда.

Добавлены методы Array#second_to_last и Array#third_to_last.

Добавлен метод #on_weekday? в Date, Time и DateTime.

Опубликованы API ActiveSupport::Executor и ActiveSupport::Reloader, чтобы позволить компонентам и библиотекам управлять и участвовать в выполнении кода приложения и процессе перезагрузки приложения.

Теперь ActiveSupport::Duration поддерживает форматирование и парсинг ISO8601.

В TaggedLogging добавлена возможность логгерам быть инициализированными несколько раз, и у них не будет общих тегов между собой.