Ruby on Rails 4.2 Release Notes =============================== Highlights in Rails 4.2: * Active Job, Action Mailer #deliver_later * Adequate Record * Web Console * Foreign key support These release notes cover only the major changes. To learn about various bug fixes and changes, please refer to the change logs or check out the [list of commits](https://github.com/rails/rails/commits/master) in the main Rails repository on GitHub. -------------------------------------------------------------------------------- NOTE: This document is a work in progress, please help to improve this by sending a [pull request](https://github.com/rails/rails/edit/master/guides/source/4_2_release_notes.md). 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](upgrading_ruby_on_rails.html#upgrading-from-rails-4-1-to-rails-4-2) Major Features -------------- ### Active Job, Action Mailer #deliver_later Active Job is a new framework in Rails 4.2. It is an adapter layer on top of queuing systems like [Resque](https://github.com/resque/resque), [Delayed Job](https://github.com/collectiveidea/delayed_job), [Sidekiq](https://github.com/mperham/sidekiq), and more. You can write your jobs with the Active Job API, and it'll run on all these queues with no changes (it comes pre-configured with an inline runner). Building on top of Active Job, Action Mailer now comes with a `#deliver_later` method, which adds your email to be sent as a job to a queue, so it doesn't bog down the controller or model. The new GlobalID library makes it easy to pass Active Record objects to jobs by serializing them in a generic form. This means you no longer have to manually pack and unpack your Active Records by passing ids. Just give the job the Active Record object, and the object will be serialized using GlobalID, and then deserialized again at run time. ### 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 [Aaron Patterson's blog post](http://tenderlovemaking.com/2014/02/19/adequaterecord-pro-like-activerecord.html). Active Record will automatically take advantage of this feature on the supported operations without any user involvement and code changes. Here are some examples of the supported operations: ```ruby Post.find 1 # First call will generate and cache the prepared statement Post.find 2 # Second call will reuse the cached statement Post.find_by_title 'first post' Post.find_by_title 'second post' post.comments post.comments(true) ``` The caching is not used in the following scenarios: - The model has a default scope - The model uses single table inheritance to inherit from another model - `find` with a list of ids. eg: ```ruby Post.find(1,2,3) OR Post.find [1,2] ``` - `find_by` with SQL fragments: ```ruby Post.find_by "published_at < ?", 2.weeks.ago ``` ### Web Console New applications generated from Rails 4.2 now come with the Web Console gem by default. Web Console is a set of debugging tools for your Rails application. It will add an interactive console on every error page, a `console` view helper and a VT100 compatible terminal. The interactive console on the error pages let you execute code where the exception originated. It's quite handy being able to introspect the state that led to the error. The `console` view helper launches an interactive console within the context of the view where it is invoked. Finally, you can launch a VT100 terminal that runs `rails console`. If you need to create or modify existing test data, you can do that straight from the browser. ### 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. ```ruby # 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](http://api.rubyonrails.org/v4.2.0/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-add_foreign_key) and [remove_foreign_key](http://api.rubyonrails.org/v4.2.0/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-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 is 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. To use the following, add `gem 'responders', '~> 2.0'` to your Gemfile: ```ruby # 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: ```ruby # 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](https://github.com/rack/rack/commit/28b014484a8ac0bbb388e7eaeeef159598ec64fc), `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 (e.g. your development environment is in a virtual machine and you would like to access it from the host machine), you would need to 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. ### 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. With a new sanitization algorithm, the sanitized output will change for certain pathological inputs. If you have particular need for the exact output of the old sanitizer, you can add `rails-deprecated_sanitizer` to your Gemfile, and it will automatically replace the new implementation. Because it is opt-in, the legacy gem will not give deprecation warnings. `rails-deprecated_sanitizer` will be supported for Rails 4.2 only; it will not be maintained for Rails 5.0. See [the blog post](http://blog.plataformatec.com.br/2014/07/the-new-html-sanitizer-in-rails-4-2/) for more detail 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: * Values in attribute selectors may need to be quoted if they contain non-alphanumeric characters. ``` a[href=/] => a[href="/"] a[href$=/] => a[href$="/"] ``` * DOMs built from HTML source containing invalid HTML with improperly nested elements may differ. For example: ``` ruby # content:
AT&T
# before: assert_select('p', 'AT&T') # => true assert_select('p', 'AT&T') # => false # now: assert_select('p', 'AT&T') # => true assert_select('p', 'AT&T') # => false ``` Railties -------- Please refer to the [Changelog][railties] for detailed changes. ### Removals * The `--skip-action-view` option has been removed from the app generator. ([Pull Request](https://github.com/rails/rails/pull/17042)) * The `rails application` command has been removed without replacement. ([Pull Request](https://github.com/rails/rails/pull/11616)) ### Deprecations * Deprecated `Rails::Rack::LogTailer` without replacement. ([Commit](https://github.com/rails/rails/commit/84a13e019e93efaa8994b3f8303d635a7702dbce)) * Deprecated missing `config.log_level` for production environments. ([Pull Request](https://github.com/rails/rails/pull/16622)) * Deprecated `rake test:all` in favor of `rake test` as it now run all tests in the `test` folder. ([Pull Request](https://github.com/rails/rails/pull/17348)) * Deprecated `rake test:all:db` in favor of `rake test:db`. ([Pull Request](https://github.com/rails/rails/pull/17348)) ### Notable changes * Introduced `web-console` in the default application Gemfile. ([Pull Request](https://github.com/rails/rails/pull/11667)) * Added a `required` option to the model generator for associations. ([Pull Request](https://github.com/rails/rails/pull/16062)) * Introduced an `after_bundle` callback for use in Rails templates. ([Pull Request](https://github.com/rails/rails/pull/16359)) * Introduced the `x` namespace for defining custom configuration options: ```ruby # config/environments/production.rb config.x.payment_processing.schedule = :daily config.x.payment_processing.retries = 3 config.x.super_debugger = true ``` These options are then available through the configuration object: ```ruby Rails.configuration.x.payment_processing.schedule # => :daily Rails.configuration.x.payment_processing.retries # => 3 Rails.configuration.x.super_debugger # => true ``` ([Commit](https://github.com/rails/rails/commit/611849772dd66c2e4d005dcfe153f7ce79a8a7db)) * Introduced `Rails::Application.config_for` to load a configuration for the current environment. ```ruby # config/exception_notification.yml: production: url: http://127.0.0.1:8080 namespace: my_app_production development: url: http://localhost:3001 namespace: my_app_development # config/production.rb Rails.application.configure do config.middleware.use ExceptionNotifier, config_for(:exception_notification) end ``` ([Pull Request](https://github.com/rails/rails/pull/16129)) * Introduce a `--skip-turbolinks` option in the app generator to not generate any turbolinks integration. ([Commit](https://github.com/rails/rails/commit/bf17c8a531bc8059d50ad731398002a3e7162a7d)) * Introduced a `bin/setup` script to enable automated setup code when bootstrapping an application. ([Pull Request](https://github.com/rails/rails/pull/15189)) * Changed default value for `config.assets.digest` to `true` in development. ([Pull Request](https://github.com/rails/rails/pull/15155)) * Introduced an API to register new extensions for `rake notes`. ([Pull Request](https://github.com/rails/rails/pull/14379)) * Introduced `Rails.gem_version` as a convenience method to return `Gem::Version.new(Rails.version)`. ([Pull Request](https://github.com/rails/rails/pull/14101)) Action Pack ----------- Please refer to the [Changelog][action-pack] for detailed changes. ### Removals * `respond_with` and the class-level `respond_to` were removed from Rails and moved to the `responders` gem (version 2.0). Add `gem 'responders', '~> 2.0'` to your `Gemfile` to continue using these features. ([Pull Request](https://github.com/rails/rails/pull/16526)) * Removed deprecated `AbstractController::Helpers::ClassMethods::MissingHelperError` in favor of `AbstractController::Helpers::MissingHelperError`. ([Commit](https://github.com/rails/rails/commit/a1ddde15ae0d612ff2973de9cf768ed701b594e8)) ### Deprecations * Deprecated the `only_path` option on `*_path` helpers. ([Commit](https://github.com/rails/rails/commit/aa1fadd48fb40dd9396a383696134a259aa59db9)) * Deprecated `assert_tag`, `assert_no_tag`, `find_tag` and `find_all_tag` in favor of `assert_select`. ([Commit](https://github.com/rails/rails-dom-testing/commit/b12850bc5ff23ba4b599bf2770874dd4f11bf750)) * Deprecated support for setting the `:to` option of a router to a symbol or a string that does not contain a `#` character: ```ruby get '/posts', to: MyRackApp => (No change necessary) get '/posts', to: 'post#index' => (No change necessary) get '/posts', to: 'posts' => get '/posts', controller: :posts get '/posts', to: :index => get '/posts', action: :index ``` ([Commit](https://github.com/rails/rails/commit/cc26b6b7bccf0eea2e2c1a9ebdcc9d30ca7390d9)) * Deprecated support for String keys in URL helpers: ```ruby # bad Rails.application.routes.url_helpers.root_path('controller' => 'posts', 'action' => 'index') # good Rails.application.routes.url_helpers.root_path(controller: 'posts', action: 'index') ``` ([Pull Request](https://github.com/rails/rails/pull/17743)) ### Notable changes * Rails will now automatically include the template's digest in ETags. ([Pull Request](https://github.com/rails/rails/pull/16527)) * `render nothing: true` or rendering a `nil` body no longer add a single space padding to the response body. ([Pull Request](https://github.com/rails/rails/pull/14883)) * Introduced the `always_permitted_parameters` option to configure which parameters are permitted globally. The default value of this configuration is `['controller', 'action']`. ([Pull Request](https://github.com/rails/rails/pull/15933)) * The `*_filter` family methods have been removed from the documentation. Their usage is discouraged in favor of the `*_action` family methods: ``` after_filter => after_action append_after_filter => append_after_action append_around_filter => append_around_action append_before_filter => append_before_action around_filter => around_action before_filter => before_action prepend_after_filter => prepend_after_action prepend_around_filter => prepend_around_action prepend_before_filter => prepend_before_action skip_after_filter => skip_after_action skip_around_filter => skip_around_action skip_before_filter => skip_before_action skip_filter => skip_action_callback ``` If your application currently depends on these methods, you should use the replacement `*_action` methods instead. These methods will be deprecated in the future and will eventually be removed from Rails. (Commit [1](https://github.com/rails/rails/commit/6c5f43bab8206747a8591435b2aa0ff7051ad3de), [2](https://github.com/rails/rails/commit/489a8f2a44dc9cea09154ee1ee2557d1f037c7d4)) * Added HTTP method `MKCALENDAR` from RFC-4791 ([Pull Request](https://github.com/rails/rails/pull/15121)) * `*_fragment.action_controller` notifications now include the controller and action name in the payload. ([Pull Request](https://github.com/rails/rails/pull/14137)) * Segments that are passed into URL helpers are now automatically escaped. ([Commit](https://github.com/rails/rails/commit/5460591f0226a9d248b7b4f89186bd5553e7768f)) * Improved the Routing Error page with fuzzy matching for route search. ([Pull Request](https://github.com/rails/rails/pull/14619)) * Added an option to disable logging of CSRF failures. ([Pull Request](https://github.com/rails/rails/pull/14280)) * When the Rails server is set to serve static assets, gzip assets will now be served if the client supports it and a pre-generated gzip file (`.gz`) is on disk. By default the asset pipeline generates `.gz` files for all compressible assets. Serving gzip files minimizes data transfer and speeds up asset requests. Always [use a CDN](http://guides.rubyonrails.org/asset_pipeline.html#cdns) if you are serving assets from your Rails server in production. ([Pull Request](https://github.com/rails/rails/pull/16466)) * The way `assert_select` works has changed; specifically a different library is used to interpret CSS selectors, build the transient DOM that the selectors are applied against, and to extract the data from that DOM. These changes should only affect edge cases. Examples: * Values in attribute selectors may need to be quoted if they contain non-alphanumeric characters. * DOMs built from HTML source containing invalid HTML with improperly nested elements may differ. * If the data selected contains entities, the value selected for comparison used to be raw (e.g. `AT&T`), and now is evaluated (e.g. `AT&T`). Action View ------------- Please refer to the [Changelog][action-view] for detailed changes. ### Deprecations * Deprecated `AbstractController::Base.parent_prefixes`. Override `AbstractController::Base.local_prefixes` when you want to change where to find views. ([Pull Request](https://github.com/rails/rails/pull/15026)) * Deprecated `ActionView::Digestor#digest(name, format, finder, options = {})`. Arguments should be passed as a hash instead. ([Pull Request](https://github.com/rails/rails/pull/14243)) ### Notable changes * `render "foo/bar"` now expands to `render template: "foo/bar"` instead of `render file: "foo/bar"`. ([Pull Request](https://github.com/rails/rails/pull/16888)) * Introduced a `#{partial_name}_iteration` special local variable for use with partials that are rendered with a collection. It provides access to the current state of the iteration via the `#index`, `#size`, `#first?` and `#last?` methods. ([Pull Request](https://github.com/rails/rails/pull/7698)) * The form helpers no longer generate a `