Rails 5.1: upcoming features

Rails 5.1: upcoming features

Presented at RailsConf, April 2017

------------------- BREAKING CHANGES -------------------------

Change Action View ERB handler from Erubis to Erubi
https://github.com/rails/rails/pull/27757

Deprecate String options :if and :unless to set/skip callbacks
https://github.com/rails/rails/commit/0952552

Deprecate :action and :controller path parameters
https://github.com/rails/rails/pull/23980

------------------- ACTIVE RECORD -------------------------

Add ActiveRecord::Base. connection_pool.stat
https://github.com/rails/rails/pull/26988

Change default primary keys to BIGINT
https://github.com/rails/rails/pull/26266

Virtual column support for MySQL and MariaDB
https://github.com/rails/rails/commit/65bf1c6

Adds support for limits in batch processing
https://github.com/rails/rails/commit/451437c

------------------- ACTIVE SUPPORT -------------------------

Update Unicode version to 9.0.0
https://github.com/rails/rails/pull/27822

DateTime#change supports :usec and :nsec options
https://github.com/rails/rails/pull/28242

Add Duration#after and #before as alias for #since and #until
https://github.com/rails/rails/pull/27721

Introduce Module#delegate_missing_to
https://github.com/rails/rails/pull/23930

------------------- ACTION VIEW -------------------------

Add option :check_parameters to current_page?
https://github.com/rails/rails/pull/27549

New syntax for Action View’s tag helpers
https://github.com/rails/rails/pull/25543

Add form_with to unify form_tag and form_for
https://github.com/rails/rails/pull/26976

------------------- RAILTIES -------------------------

Display railtie class name in "rails initializers"
https://github.com/rails/rails/pull/25257

Added a shared section to config/secrets.yml
https://github.com/rails/rails/commit/e530534

Add encrypted secrets in config/secrets.yml.enc
https://github.com/rails/rails/pull/28038

Drop jQuery as a dependency and include rails-ujs
https://github.com/rails/rails/pull/27113

Add Yarn support in new apps using --yarn option
https://github.com/rails/rails/pull/26836

Basic --webpack delegation to new webpacker gem
https://github.com/rails/rails/pull/27288

------------------- ACTION PACK -------------------------

Capybara integration with Rails (AKA System Tests)
https://github.com/rails/rails/pull/26703

Custom URL helpers and polymorphic mapping
https://github.com/rails/rails/pull/23138

------------------- ACTIVE JOB -------------------------

Add retry_on/discard_on for better exception handling
https://github.com/rails/rails/pull/25991

------------------- ACTION MAILER -------------------------

Add parameterized invocation of mailers
https://github.com/rails/rails/pull/27825

0722f1ff8d0a69bce57ebdb93dafc395?s=128

Claudio B.

April 13, 2017
Tweet

Transcript

  1. Slides at speakerdeck.com/claudiob Rails 5.1: awesome features & breaking changes

  2. Rails 5.1: awesome features & breaking changes $ git log

    v4.2.0..v5.0.0 # => 18 months # => 962 authors # => 9,998 commits $ git log v5.0.0..v5.1.0.rc2 # => 9 months # => 450 authors # => 4,065 commits 5.0 5.1
  3. Breaking changes

  4. PR 27757 by Jeremy Evans Change Action View ERB handler

    from Erubis to Erubi Breaking change
  5. commit 0952552 by Ryuta Kamizono Deprecate String options :if and

    :unless to set/skip callbacks Breaking change
  6. Deprecate String options to set/skip callbacks class Post < ApplicationRecord

    before_save :set_no_title, unless: 'title.present?' skip_callback :save, :before, :set_no_title, if: 'persisted?' private def set_no_title self.title = 'No title' end end 5.0
  7. Deprecate String options to set/skip callbacks class Post < ApplicationRecord

    before_save :set_no_title, unless: -> { title.present? } skip_callback :save, :before, :set_no_title, if: :persisted? private def set_no_title self.title = 'No title' end end 5.1
  8. PR 23980 by Andrew White Deprecate :action and :controller path

    parameters Breaking change
  9. Deprecate :action and :controller path parameters # config/routes.rb get ':controller(/:action(/:id))'

    [CVE-2014-0130] Directory traversal vulnerability (4.1.1, 4.0.5) [CVE-2015-7581] Object leak vulnerability (4.2.5, 4.1.13) # config/routes.rb get ':controller(/:action(/:id))' # deprecated get 'photos(/:id)', to: :display # acceptable 5.0 5.1
  10. Active Record

  11. Change default primary keys to BIGINT PR 26266 by Jon

    McCartie Active Record
  12. Virtual column support for MySQL and MariaDB commit 65bf1c6 by

    Ryuta Kamizono Active Record
  13. Virtual column support for MySQL and MariaDB class CreateUsers <

    ActiveRecord::Migration[5.1] def change create_table :users do |t| t.string :name t.virtual :upper_name, type: :string, as: "UPPER(name)" t.virtual :name_length, type: :integer, as: "LENGTH(name)", stored: true, index: true end end end 5.1
  14. commit 451437c by Xavier Noria Adds support for limits in

    batch processing Active Record
  15. Adds support for limits in batch processing Post.limit(500).find_each.map(&:title) # Scoped

    order and limit are ignored, it's forced to be batch order and batch size. # => Post Load (0.2ms) SELECT "posts".* FROM "posts" ORDER BY "posts"."id" ASC LIMIT ? [["LIMIT", 1000]] Post.limit(500).find_each.map(&:title) # => Post Load (0.1ms) SELECT "posts".* FROM "posts" ORDER BY "posts"."id" ASC LIMIT ? [["LIMIT", 500]] 5.0 5.1
  16. Active Support

  17. Update Unicode version to 9.0.0 PR 27822 by Fumiaki Matsushima

    Active Support
  18. Update Unicode version to 9.0.0 ActiveSupport::Multibyte::Unicode::UNICODE_VERSION # => "8.0.0" "

    " ".mb_chars.grapheme_length # => 4 " " ".mb_chars.reverse # => " " ActiveSupport::Multibyte::Unicode::UNICODE_VERSION # => "9.0.0" " " ".mb_chars.grapheme_length # => 1 " " ".mb_chars.reverse # => " " " 5.0 5.1
  19. Add Duration#after and #before as alias for #since and #until

    PR 27721 by Nick Johnstone Active Support
  20. Add Duration#after and #before as aliases… 2.weeks.since(christmas_day) # => Mon,

    08 Jan 2018 5.days.until(christmas_day) # => Wed, 20 Dec 2017 2.weeks.after(christmas_day) # => Mon, 08 Jan 2018 5.days.before(christmas_day) # => Wed, 20 Dec 2017 5.0 5.1
  21. Introduce Module# delegate_missing_to PR 23930 by Genadi Samokovarov Active Support

  22. Introduce Module#delegate_missing_to class OrderCompletion delegate :destroy, :update, …more methods…, to:

    :@order def initialize(order) @order = order end def create OrderCompletionNotification.deliver(@order) if @order.save end end 5.0
  23. Introduce Module#delegate_missing_to class OrderCompletion delegate_missing_to :@order def initialize(order) @order =

    order end def create OrderCompletionNotification.deliver(@order) if @order.save end end 5.1
  24. Action View

  25. New syntax for Action View’s tag helpers PR 25543 by

    Marek Kirejczyk Action View
  26. New syntax for Action View’s tag helpers tag(:br, nil, true)

    <%= content_tag :div, class: "strong" do -%> Hello world! <% end -%> tag.br <%= tag.div class: "strong" do %> Hello world! <% end %> 5.0 5.1
  27. PR 26976 by Kasper Timm Hansen Add form_with to unify

    form_tag and form_for Action View
  28. Add form_with to unify form_tag and form_for # app/views/posts/show.html.erb <%=

    form_for @post, method: :delete do |f| %> <%= f.submit 'Delete post' %> <% end %> # app/views/posts/show.html.erb <%= form_with model: @post, method: :delete do |f| %> <%= f.submit 'Delete post' %> <% end %> 5.0 5.1
  29. Add form_with to unify form_tag and form_for # app/views/posts/index.html.erb <%=

    form_tag '/posts/1', method: :delete do %> <%= submit_tag 'Delete post #1' %> <% end %> # app/views/posts/index.html.erb <%= form_with url: '/posts/1', method: :delete do |f| %> <%= submit_tag 'Delete post #1' %> <% end %> 5.0 5.1
  30. Railties

  31. PR 25257 by ta1kt0me Display railtie class name in "rails

    initializers" Railties
  32. Display railtie class name in `rails initializers` $ rails initializers

    set_load_path set_load_path [124 more…] $ rails initializers ActionView::Railtie.set_load_path ActionCable::Engine.set_load_path [126 more…] 5.0 5.1
  33. commit e530534 by David Heinemeier Hansson Added a shared section

    to config/secrets.yml Railties
  34. Added a shared section to config/secrets.yml # config.secrets.yml default: &default

    email_from: noreply@example.com development: <<: *default shared: email_from: noreply@example.com 5.0 5.1
  35. Add encrypted secrets in config/ secrets.yml.enc PR 28038 by Kasper

    Timm Hansen Railties
  36. Add encrypted secrets in config/secrets.yml.enc # config/secrets.yml # Do not

    keep production secrets in the repository, # instead read values from the environment. production: secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> $ rails console production > Rails.application.secrets # => {:secret_key_base=>nil, :secret_token=>nil} 5.0 5.0
  37. Add encrypted secrets in config/secrets.yml.enc $ rails secrets:setup Adding config/secrets.yml.key

    to store the encryption key: 667c… $ more config/secrets.yml.enc # QMdWtttAU5ZJVrsJRFot4j0gCgaqjjsLA0CIFnAhdc+LByI4ILZFwR $ EDITOR=vi rails secrets:edit # See `secrets.yml` for tips on generating suitable keys. production: api_key: "466aac22e6a869134be3d09b9e89232fc2c228" 5.1
  38. PR 27113 by Guillermo Iguaran Drop jQuery as a dependency

    and include rails-ujs Railties
  39. Drop jQuery as a dependency and include rails-ujs <%= link_to

    'Destroy', post, method: :delete, data: {confirm: 'Are you sure?'} %> <a data-confirm="Are you sure?" data-method="delete" href="/posts/7">Destroy</a>
  40. Drop jQuery as a dependency and include rails-ujs <%= link_to

    'Destroy', post, method: :delete, data: {confirm: 'Are you sure?'} %> <a data-confirm="Are you sure?" data-method="delete" href="/posts/7">Destroy</a>
  41. Drop jQuery as a dependency and include rails-ujs # Gemfile

    gem 'jquery-rails' # app/assets/javascripts/application.js //= require jquery //= require jquery_ujs # app/assets/javascripts/application.js //= require rails-ujs 5.0 5.1
  42. PR 26836 by Liceth Ovalles Rodriguez Add Yarn support in

    new apps using --yarn option Railties
  43. Add Yarn support in new apps $ yarn init $

    yarn add bootstrap $ echo ".node_modules/" >> .gitignore # config/initializers/assets.rb config.assets.paths << Rails.root.join('node_modules') # app/assets/stylesheets/application.css *= require bootstrap/dist/css/bootstrap # app/assets/javascripts/application.js //= require bootstrap/dist/js/bootstrap 5.0
  44. Add Yarn support in new apps $ bin/yarn init $

    bin/yarn add bootstrap # app/assets/stylesheets/application.css *= require bootstrap/dist/css/bootstrap # app/assets/javascripts/application.js //= require bootstrap/dist/js/bootstrap 5.1
  45. PR 27288 by David Heinemeier Hansson Basic --webpack delegation to

    new webpacker gem Railties
  46. Basic --webpack delegation to new webpacker gem $ rails new

    app_name --webpack 5.1 rails webpacker:install Creating javascript app source directory create app/javascript create app/javascript/packs/application.js Copying binstubs create bin/webpack-dev-server create bin/webpack-watcher create bin/webpack Copying webpack core config and loaders create config/webpack/configuration.js create config/webpack/development.js create config/webpack/development.server.js create config/webpack/development.server.yml create config/webpack/paths.yml create config/webpack/production.js create config/webpack/shared.js create config/webpack/loaders create config/webpack/loaders/assets.js create config/webpack/loaders/babel.js create config/webpack/loaders/coffee.js create config/webpack/loaders/erb.js create config/webpack/loaders/sass.js create .postcssrc.yml create .gitignore Installing all JavaScript dependencies run ./bin/yarn add webpack webpack-merge…
  47. Basic --webpack delegation to new webpacker gem $ webpack-dev-server #

    app/views/layouts/application.html.erb <%= javascript_pack_tag 'application' %> <%= stylesheet_pack_tag 'application' %> # app/javascript/packs/application.js.erb require('moment') <% helpers = ActionController::Base.helpers %> var railsImagePath = "<%= helpers.image_path('rails.png') %>" 5.1
  48. Action Pack

  49. PR 26703 by Eileen M. Uchitelle Capybara integration with Rails

    (AKA System Tests) Action Pack
  50. Capybara integration with Rails (AKA System Tests)

  51. Capybara integration with Rails (AKA System Tests) # Gemfile group

    :development, :test do gem 'capybara' gem 'selenium-webdriver' end # test/test_helper.rb require 'capybara/rails' require 'capybara/minitest' […] 5.0
  52. Capybara integration with Rails (AKA System Tests) # test/test_helper.rb class

    ActionDispatch::IntegrationTest include Capybara::DSL include Capybara::Minitest::Assertions Capybara.register_driver :selenium do |app| Capybara::Selenium::Driver.new app, browser: :chrome end Capybara.default_driver = :selenium end 5.0
  53. Custom URL helpers and polymorphic mapping $ rails test:integration #

    => 1 runs, 1 assertions, 0 failures # test/integration/posts_test.rb require "test_helper" class PostsTest < ActionDispatch::IntegrationTest test "visiting the 'posts' page" do visit '/posts' assert_selector 'h1', text: 'Posts' end end 5.0
  54. Capybara integration with Rails (AKA System Tests) # test/system/posts_test.rb require

    "application_system_test_case" class PostsTest < ApplicationSystemTestCase test "visiting the 'posts' page" do visit posts_url assert_selector 'h1', text: 'Posts' end end $ rails test:system # => 1 runs, 1 assertions, 0 failures 5.1
  55. PR 23138 by Andrew White Custom URL helpers and polymorphic

    mapping Action Pack
  56. Custom URL helpers and polymorphic mapping

  57. Custom URL helpers and polymorphic mapping <a href="/posts/1#content-2">Comment #2</a> <%=

    link_to "Comment #2", post_path(@comment.post, anchor: 'content-2') %> # config/routes.rb direct(:embedded_content) do |content| url_for [content.post, anchor: "content-#{content.id}"] end <%= link_to "Comment #2", embedded_content_path(@comment) %> 5.0 5.1
  58. Custom URL helpers and polymorphic mapping <form action="/profile" accept-charset="UTF-8" method="post">

    … </form>
  59. Custom URL helpers and polymorphic mapping <%= form_for @profile do

    |f| %> … <% end %> 5.0
  60. Custom URL helpers and polymorphic mapping # config/routes.rb resource :profile

    # app/assets/views/profiles/new.html.erb <%= form_for @profile, url: profile_path(@profile) do |f| %> # config/routes.rb resource :profile resolve('Profile') { [:profile] } # app/assets/views/profiles/new.html.erb <%= form_for @profile do |f| %> 5.0 5.1
  61. Rails 5.1: awesome features & breaking changes speakerdeck.com/claudiob Thanks!

  62. None
  63. One more thing… Extra time? Extra slides!

  64. PR 26988 by Pavel Evstigneev Add ActiveRecord::Base. connection_pool.stat Active Record

  65. Add ActiveRecord::Base. connection_pool.stat p ActiveRecord::Base.connection_pool.stat { size: 25, connections: 1,

    busy: 1, dead: 0, idle: 0, waiting: 0, checkout_timeout: 5 } 5.1
  66. PR 28242 by Andrew White DateTime#change supports :usec and :nsec

    options Active Support
  67. DateTime#change supports :usec and :nsec options now = DateTime.now now.to_f

    # => 1490028163.625132 now.change(usec: 0).to_f # => 1490028163.625132 now = DateTime.now now.to_f # => 1490028163.625132 now.change(usec: 0).to_f # => 1490028163.0 DateTime.now.end_of_day.nsec # => 999_999_999 5.0 5.1
  68. PR 27549 by Maksym Pugach Add option :check_parameters to current_page?

    Action View
  69. Add :check_parameters option to current_page? # From http://www.example.com/shop/checkout?order=desc&page=1 current_page? 'http://www.example.com/shop/checkout'

    # => true # From http://www.example.com/shop/checkout?order=desc&page=1 current_page? 'http://www.example.com/shop/checkout', check_parameters: true # => false 5.0 5.1
  70. Active Job

  71. PR 25991 by David Heinemeier Hansson Add retry_on/ discard_on for

    better exception handling Active Job
  72. Add retry_on/discard_on for exception handling class SiteScraperJob < ActiveJob::Base rescue_from(ApocalypticException)

    rescue_from(ErrorLoadingSite) do retry_job queue: :low_priority end def perform(*args) # raise ErrorLoadingSite if cannot scrape end end 5.0
  73. Add retry_on/discard_on for exception handling class SiteScraperJob < ActiveJob::Base discard_on

    ApocalypticException retry_on ErrorLoadingSite # retry_on ErrorLoadingSite, wait: :exponentially_longer # retry_on ErrorLoadingSite, wait: ->(attempts) { attempts * 2 } def perform(*args) # raise ErrorLoadingSite if cannot scrape end end 5.1
  74. Action Mailer

  75. Add parameterized invocation of mailers PR 27825 by David Heinemeier

    Hansson Action Mailer
  76. Add parameterized invocation of mailers class PartyMailer < ApplicationMailer def

    birthday_invite(guest) mail subject: "Come to my birthday!", to: guest.email_address end def wedding_invite(guest) mail subject: "Come to my wedding!", to: guest.email_address end end PartyMailer.birthday_invite(current_user) 5.0
  77. Add parameterized invocation of mailers class PartyMailer < ApplicationMailer before_action

    { @guest = params[:guest] } default to: -> { @guest.email_address } def birthday_invite mail subject: "Come to my birthday!" end def wedding_invite; mail subject: "Come to my wedding!"; end end PartyMailer.with(guest: current_user).birthday_invite 5.1
  78. Rails 5.1: awesome features & breaking changes Thanks!