123456789_123456789_123456789_123456789_123456789_

DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.

Ruby on Rails 4.2 Release Notes

Highlights in Rails 4.2:

These release notes cover only the major changes. To learn about other features, bug fixes, and changes, please refer to the changelogs or check out the list of commits in the main Rails repository on GitHub.


Upgrading to Rails 4.2

If you're upgrading an existing application, it's a great idea to have good test coverage before going in. You should also first upgrade to Rails 4.1 in case you haven't and make sure your application still runs as expected before attempting to upgrade to Rails 4.2. A list of things to watch out for when upgrading is available in the guide Upgrading Ruby on Rails.

Major Features

Active Job

Active Job is a new framework in Rails 4.2. It is a common interface on top of queuing systems like Resque, href="https://github.com/collectiveidea/delayed_job">https://github.com/collectiveidea/delayed_job Delayed Job, Sidekiq, and more.

Jobs written with the Active Job API run on any of the supported queues thanks to their respective adapters. Active Job comes pre-configured with an inline runner that executes jobs right away.

Jobs often need to take Active Record objects as arguments. Active Job passes object references as URIs (uniform resource identifiers) instead of marshaling the object itself. The new Global ID library builds URIs and looks up the objects they reference. Passing Active Record objects as job arguments just works by using Global ID internally.

For example, if trashable is an Active Record object, then this job runs just fine with no serialization involved:

class TrashableCleanupJob < ActiveJob::Base
  def perform(trashable, depth)
    trashable.cleanup(depth)
  end
end

See the Active Job Basics guide for more information.

Asynchronous Mails

Building on top of Active Job, Action Mailer now comes with a deliver_later method that sends emails via the queue, so it doesn't block the controller or model if the queue is asynchronous (the default inline queue blocks).

Sending emails right away is still possible with deliver_now.

Adequate Record

Adequate Record is a set of performance improvements in Active Record that makes common find and find_by calls and some association queries up to 2x faster.

It works by caching common SQL queries as prepared statements and reusing them on similar calls, skipping most of the query-generation work on subsequent calls. For more details, please refer to href="http://tenderlovemaking.com/2014/02/19/adequaterecord-pro-like-activerecord.html">http://tenderlovemaking.com/2014/02/19/adequaterecord-pro-like-activerecord.html Aaron Patterson's blog post.

Active Record will automatically take advantage of this feature on supported operations without any user involvement or code changes. Here are some examples of supported operations:

Post.find(1)  # First call generates and cache the prepared statement
Post.find(2)  # Subsequent calls reuse the cached prepared statement

Post.find_by_title('first post')
Post.find_by_title('second post')

Post.find_by(title: 'first post')
Post.find_by(title: 'second post')

post.comments
post.comments(true)

It's important to highlight that, as the examples above suggest, the prepared statements do not cache the values passed in the method calls; rather, they have placeholders for them.

Caching is not used in the following scenarios:

Web Console

New applications generated with Rails 4.2 now come with the href="https://github.com/rails/web-console">https://github.com/rails/web-console Web Console gem by default. Web Console adds an interactive Ruby console on every error page and provides a console view and controller helpers.

The interactive console on error pages lets you execute code in the context of the place where the exception originated. The console helper, if called anywhere in a view or controller, launches an interactive console with the final context, once rendering has completed.

Foreign Key Support

The migration DSL now supports adding and removing foreign keys. They are dumped to schema.rb as well. At this time, only the mysql, mysql2 and postgresql adapters support foreign keys.

# add a foreign key to `articles.author_id` referencing `authors.id`
add_foreign_key :articles, :authors

# add a foreign key to `articles.author_id` referencing `users.lng_id`
add_foreign_key :articles, :users, column: :author_id, primary_key: "lng_id"

# remove the foreign key on `accounts.branch_id`
remove_foreign_key :accounts, :branches

# remove the foreign key on `accounts.owner_id`
remove_foreign_key :accounts, column: :owner_id

See the API documentation on add_foreign_key and remove_foreign_key for a full description.

Incompatibilities

Previously deprecated functionality has been removed. Please refer to the individual components for new deprecations in this release.

The following changes may require immediate action upon upgrade.

render with a String Argument

Previously, calling render "foo/bar" in a controller action was equivalent to render file: "foo/bar". In Rails 4.2, this has been changed to mean render template: "foo/bar" instead. If you need to render a file, please change your code to use the explicit form (render file: "foo/bar") instead.

respond_with / Class-Level respond_to

respond_with and the corresponding class-level respond_to have been moved to the responders gem. Add gem 'responders', '~> 2.0' to your Gemfile to use it:

# app/controllers/users_controller.rb

class UsersController < ApplicationController
  respond_to :html, :json

  def show
    @user = User.find(params[:id])
    respond_with @user
  end
end

Instance-level respond_to is unaffected:

# app/controllers/users_controller.rb

class UsersController < ApplicationController
  def show
    @user = User.find(params[:id])
    respond_to do |format|
      format.html
      format.json { render json: @user }
    end
  end
end

Default Host for rails server

Due to a change in Rack, rails server now listens on localhost instead of 0.0.0.0 by default. This should have minimal impact on the standard development workflow as both http://127.0.0.1:3000 and http://localhost:3000 will continue to work as before on your own machine.

However, with this change you will no longer be able to access the Rails server from a different machine, for example if your development environment is in a virtual machine and you would like to access it from the host machine. In such cases, please start the server with rails server -b 0.0.0.0 to restore the old behavior.

If you do this, be sure to configure your firewall properly such that only trusted machines on your network can access your development server.

Changed status option symbols for render

Due to a change in Rack, the symbols that the render method accepts for the :status option have changed:

Keep in mind that if calling render with an unknown symbol, the response status will default to 500.

HTML Sanitizer

The HTML sanitizer has been replaced with a new, more robust, implementation built upon Loofah and Nokogiri. The new sanitizer is more secure and its sanitization is more powerful and flexible.

Due to the new algorithm, the sanitized output may be different for certain pathological inputs.

If you have a particular need for the exact output of the old sanitizer, you can add the rails-deprecated_sanitizer gem to the Gemfile, to have the old behavior. The gem does not issue deprecation warnings because it is opt-in.

rails-deprecated_sanitizer will be supported for Rails 4.2 only; it will not be maintained for Rails 5.0.

See this blog post for more details on the changes in the new sanitizer.

assert_select

assert_select is now based on Nokogiri. As a result, some previously-valid selectors are now unsupported. If your application is using any of these spellings, you will need to update them:

Furthermore substitutions have changed syntax.

Now you have to use a :match CSS-like selector:

assert_select ":match('id', ?)", 'comment_1'

Additionally Regexp substitutions look different when the assertion fails. Notice how /hello/ here:

assert_select(":match('id', ?)", /hello/)

becomes "(?-mix:hello)":

Expected at least 1 element matching "div:match('id', "(?-mix:hello)")", found 0..
Expected 0 to be >= 1.

See the Rails Dom Testing documentation for more on assert_select.

Railties

Please refer to the Changelog for detailed changes.

Removals

Deprecations

Notable changes

Action Pack

Please refer to the Changelog for detailed changes.

Removals

Deprecations

Notable changes

Action View

Please refer to the Changelog for detailed changes.

Deprecations

Notable changes

Action Mailer

Please refer to the Changelog for detailed changes.

Deprecations

Notable changes

Active Record

Please refer to the Changelog for detailed changes.

Removals

Deprecations

Notable changes

Active Model

Please refer to the Changelog for detailed changes.

Removals

Deprecations

Notable changes

Active Support

Please refer to the Changelog for detailed changes.

Removals

Deprecations

Notable changes

Credits

See the full list of contributors to Rails for the many people who spent many hours making Rails the stable and robust framework it is today. Kudos to all of them.