Ruby on Rails 4.0 Release Notes =============================== Highlights in Rails 4.0: (WIP) * Ruby 1.9.3 only * Strong Parameters * Queue API * Caching Improvements * ActionController::Live These release notes cover the major changes, but do not include each bug-fix and changes. If you want to see everything, check out the [list of commits](https://github.com/rails/rails/commits/master) in the main Rails repository on GitHub. -------------------------------------------------------------------------------- Upgrading to Rails 4.0 ---------------------- TODO. This is a WIP guide. 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 3.2 in case you haven't and make sure your application still runs as expected before attempting an update to Rails 4.0. Then take heed of the following changes: ### Rails 4.0 requires at least Ruby 1.9.3 Rails 4.0 requires Ruby 1.9.3 or higher. Support for all of the previous Ruby versions has been dropped officially and you should upgrade as early as possible. ### What to update in your apps * Update your Gemfile to depend on * `rails = 4.0.0` * `sass-rails ~> 3.2.3` * `coffee-rails ~> 3.2.1` * `uglifier >= 1.0.3` TODO: Update the versions above. * Rails 4.0 removes `vendor/plugins` completely. You have to replace these plugins by extracting them as gems and adding them in your Gemfile. If you choose not to make them gems, you can move them into, say, `lib/my_plugin/*` and add an appropriate initializer in `config/initializers/my_plugin.rb`. TODO: Configuration changes in environment files Creating a Rails 4.0 application -------------------------------- ``` You should have the 'rails' rubygem installed $ rails new myapp $ cd myapp ``` ### Vendoring Gems Rails now uses a `Gemfile` in the application root to determine the gems you require for your application to start. This `Gemfile` is processed by the [Bundler](https://github.com/carlhuda/bundler) gem, which then installs all your dependencies. It can even install all the dependencies locally to your application so that it doesn't depend on the system gems. More information: [Bundler homepage](http://gembundler.com) ### Living on the Edge `Bundler` and `Gemfile` makes freezing your Rails application easy as pie with the new dedicated `bundle` command. If you want to bundle straight from the Git repository, you can pass the `--edge` flag: ``` $ rails new myapp --edge ``` If you have a local checkout of the Rails repository and want to generate an application using that, you can pass the `--dev` flag: ``` $ ruby /path/to/rails/railties/bin/rails new myapp --dev ``` Major Features -------------- Moved to a Plugin ----------------- With Rails 4 several pieces have been extracted. While Rails won't ship with these features anymore, you can simply add the extracted plugin to your `Gemfile` to bring the functionality back. * Hash-based & Dynamic finder methods ([Github](https://github.com/rails/activerecord-deprecated_finders)) * Mass assignment protection in Active Record models ([Github](https://github.com/rails/protected_attributes), [Pull Request](https://github.com/rails/rails/pull/7251)) * ActiveRecord::SessionStore ([Github](https://github.com/rails/activerecord-session_store), [Pull Request](https://github.com/rails/rails/pull/7436)) * Active Record Observers ([Github](https://github.com/rails/rails-observers), [Commit](https://github.com/rails/rails/commit/39e85b3b90c58449164673909a6f1893cba290b2)) * Active Resource ([Github](https://github.com/rails/activeresource), [Pull Request](https://github.com/rails/rails/pull/572), [Blog](http://yetimedia.tumblr.com/post/35233051627/activeresource-is-dead-long-live-activeresource)) * Action Caching ([Github](https://github.com/rails/actionpack-action_caching), [Pull Request](https://github.com/rails/rails/pull/7833)) * Page Caching ([Github](https://github.com/rails/actionpack-page_caching), [Pull Request](https://github.com/rails/rails/pull/7833)) Documentation ------------- * Guides are rewritten in GitHub Flavored Markdown. * Guides have a responsive design. Railties -------- * Ensure that RAILS_ENV is set when accessing Rails.env. * Don't eager-load app/assets and app/views. * Add `.rake` to list of file extensions included by `rake notes` and `rake notes:custom`. * New test locations `test/models`, `test/helpers`, `test/controllers`, and `test/mailers`. Corresponding rake tasks added as well. ([Pull Request](https://github.com/rails/rails/pull/7878)) * Set a different cache per environment for assets pipeline through `config.assets.cache`. * `Rails.public_path` now returns a Pathname object. * Remove highly uncommon `config.assets.manifest` option for moving the manifest path. This option is now unsupported in sprockets-rails. * Add `config.action_controller.permit_all_parameters` to disable StrongParameters protection, it's false by default. * Remove `config.active_record.whitelist_attributes` and `config.active_record.mass_assignment_sanitizer` from new applications since MassAssignmentSecurity has been extracted from Rails. * Change `rails new` and `rails plugin new` generators to name the `.gitkeep` files as `.keep` in a more SCM-agnostic way. Change `--skip-git` option to only skip the `.gitignore` file and still generate the `.keep` files. Add `--skip-keeps` option to skip the `.keep` files. * Fixed support for DATABASE_URL environment variable for rake db tasks. * rails dbconsole now can use SSL for MySQL. The database.yml options sslca, sslcert, sslcapath, sslcipher and sslkey now affect rails dbconsole. * Correctly handle SCRIPT_NAME when generating routes to engine in application that's mounted at a sub-uri. With this behavior, you *should not* use default_url_options[:script_name] to set proper application's mount point by yourself. * `config.threadsafe!` is deprecated in favor of `config.eager_load` which provides a more fine grained control on what is eager loaded. * The migration generator will now produce AddXXXToYYY/RemoveXXXFromYYY migrations with references statements, for instance rails g migration AddReferencesToProducts user:references supplier:references{polymorphic} will generate the migration with: add_reference :products, :user, index: true add_reference :products, :supplier, polymorphic: true, index: true * Allow scaffold/model/migration generators to accept a `polymorphic` modifier for `references`/`belongs_to`, for instance ``` rails g model Product supplier:references{polymorphic} ``` will generate the model with `belongs_to :supplier, polymorphic: true` association and appropriate migration. * Set `config.active_record.migration_error` to `:page_load` for development. * Add runner to `Rails::Railtie` as a hook called just after runner starts. * Add `/rails/info/routes` path which displays the same information as `rake routes`. * Improved `rake routes` output for redirects. * Load all environments available in `config.paths["config/environments"]`. * Add `config.queue_consumer` to change the job queue consumer from the default `ActiveSupport::ThreadedQueueConsumer`. * Add `Rails.queue` for processing jobs in the background. * Remove `Rack::SSL` in favour of `ActionDispatch::SSL`. * Allow to set class that will be used to run as a console, other than IRB, with `Rails.application.config.console=`. It's best to add it to console block. ```ruby # it can be added to config/application.rb console do # this block is called only when running console, # so we can safely require pry here require "pry" config.console = Pry end ``` * Add a convenience method `hide!` to Rails generators to hide the current generator namespace from showing when running `rails generate`. * Scaffold now uses `content_tag_for` in `index.html.erb`. * `Rails::Plugin` is removed. Instead of adding plugins to `vendor/plugins`, use gems or bundler with path or git dependencies. ### Deprecations Action Mailer ------------- * Allow to set default Action Mailer options via `config.action_mailer.default_options=`. * Raise an `ActionView::MissingTemplate` exception when no implicit template could be found. * Asynchronously send messages via the Rails Queue. ([Pull Request](https://github.com/rails/rails/pull/6839)) * Delivery Options (such as SMTP Settings) can now be set dynamically per mailer action. Delivery options are set via :delivery_method_options key on mail. ```ruby def welcome_mailer(user,company) delivery_options = { user_name: company.smtp_user, password: company.smtp_password, address: company.smtp_host } mail(to: user.email, subject: "Welcome!", delivery_method_options: delivery_options) end ``` * Allow for callbacks in mailers similar to ActionController::Base. You can now set up headers/attachments using `before_filter` or `after_filter`. You could also change delivery settings or prevent delivery in an after filter based on instance variables set in your mailer action. You have access to `ActionMailer::Base` instance methods like `message`, `attachments`, `headers`. Action Pack ----------- ### Action Controller * Add `ActionController::Flash.add_flash_types` method to allow people to register their own flash types. e.g.: ```ruby class ApplicationController add_flash_types :error, :warning end ``` If you add the above code, you can use `<%= error %>` in an erb, and `redirect_to /foo, :error => 'message'` in a controller. * Encrypted Cookies + Sign using Derived Keys. ([Pull Request](https://github.com/rails/rails/pull/8112)) * Remove Active Model dependency from Action Pack. * Support unicode characters in routes. Route will be automatically escaped, so instead of manually escaping: ```ruby get Rack::Utils.escape('こんにちは') => 'home#index' ``` You just have to write the unicode route: ```ruby get 'こんにちは' => 'home#index' ``` * Return proper format on exceptions. * Extracted redirect logic from `ActionController::ForceSSL::ClassMethods.force_ssl` into `ActionController::ForceSSL#force_ssl_redirect`. * URL path parameters with invalid encoding now raise `ActionController::BadRequest`. * Malformed query and request parameter hashes now raise `ActionController::BadRequest`. * `respond_to` and `respond_with` now raise `ActionController::UnknownFormat` instead of directly returning head 406. The exception is rescued and converted to 406 in the exception handling middleware. * JSONP now uses `application/javascript` instead of `application/json` as the MIME type. * Session arguments passed to process calls in functional tests are now merged into the existing session, whereas previously they would replace the existing session. This change may break some existing tests if they are asserting the exact contents of the session but should not break existing tests that only assert individual keys. * Forms of persisted records use always PATCH (via the `_method` hack). * For resources, both PATCH and PUT are routed to the `update` action. * Don't ignore `force_ssl` in development. This is a change of behavior - use an `:if` condition to recreate the old behavior. ```ruby class AccountsController < ApplicationController force_ssl :if => :ssl_configured? def ssl_configured? !Rails.env.development? end end ``` #### Deprecations * Deprecated `ActionController::Integration` in favour of `ActionDispatch::Integration`. * Deprecated `ActionController::IntegrationTest` in favour of `ActionDispatch::IntegrationTest`. * Deprecated `ActionController::PerformanceTest` in favour of `ActionDispatch::PerformanceTest`. * Deprecated `ActionController::AbstractRequest` in favour of `ActionDispatch::Request`. * Deprecated `ActionController::Request` in favour of `ActionDispatch::Request`. * Deprecated `ActionController::AbstractResponse` in favour of `ActionDispatch::Response`. * Deprecated `ActionController::Response` in favour of `ActionDispatch::Response`. * Deprecated `ActionController::Routing` in favour of `ActionDispatch::Routing`. ### Action Dispatch * Add Routing Concerns to declare common routes that can be reused inside others resources and routes. Code before: ```ruby resources :messages do resources :comments end resources :posts do resources :comments resources :images, only: :index end ``` Code after: ```ruby concern :commentable do resources :comments end concern :image_attachable do resources :images, only: :index end resources :messages, concerns: :commentable resources :posts, concerns: [:commentable, :image_attachable] ``` * Show routes in exception page while debugging a `RoutingError` in development. * Helper methods for HTML5 inputs. ([Pull Request](https://github.com/rails/rails/pull/6359)) * Include `mounted_helpers` (helpers for accessing mounted engines) in `ActionDispatch::IntegrationTest` by default. * Added `ActionDispatch::SSL` middleware that when included force all the requests to be under HTTPS protocol. * Copy literal route constraints to defaults so that url generation know about them. The copied constraints are `:protocol`, `:subdomain`, `:domain`, `:host` and `:port`. * Allows `assert_redirected_to` to match against a regular expression. * Adds a backtrace to the routing error page in development. * `assert_generates`, `assert_recognizes`, and `assert_routing` all raise `Assertion` instead of `RoutingError`. * Allows the route helper root to take a string argument. For example, `root 'pages#main'` as a shortcut for `root to: 'pages#main'`. * Adds support for the PATCH verb: Request objects respond to `patch?`. Routes now have a new `patch` method, and understand `:patch` in the existing places where a verb is configured, like `:via`. Functional tests have a new method `patch` and integration tests have a new method `patch_via_redirect`. If `:patch` is the default verb for updates, edits are tunneled as `PATCH` rather than as `PUT` and routing acts accordingly. * Integration tests support the OPTIONS method. * `expires_in` accepts a `must_revalidate` flag. If true, "must-revalidate" is added to the `Cache-Control` header. * Default responder will now always use your overridden block in `respond_with` to render your response. * Turn off verbose mode of `rack-cache`, we still have `X-Rack-Cache` to check that info. #### Deprecations ### Action View * Remove Active Model dependency from Action Pack. * Allow to use `mounted_helpers` (helpers for accessing mounted engines) in `ActionView::TestCase`. * Make current object and counter (when it applies) variables accessible when rendering templates with `:object` or `:collection`. * Allow to lazy load `default_form_builder` by passing a string instead of a constant. * Add index method to `FormBuilder` class. * Adds support for layouts when rendering a partial with a given collection. * Remove `:disable_with` in favor of `data-disable-with` option from `submit_tag`, `button_tag` and `button_to` helpers. * Remove `:mouseover` option from `image_tag` helper. * Templates without a handler extension now raises a deprecation warning but still defaults to `ERb`. In future releases, it will simply return the template content. * Add a `divider` option to `grouped_options_for_select` to generate a separator optgroup automatically, and deprecate prompt as third argument, in favor of using an options hash. * Add `time_field` and `time_field_tag` helpers which render an `input[type="time"]` tag. * Removed old `text_helper` apis for `highlight`, `excerpt` and `word_wrap`. * Remove the leading \n added by textarea on `assert_select`. * Changed default value for `config.action_view.embed_authenticity_token_in_remote_forms` to false. This change breaks remote forms that need to work also without JavaScript, so if you need such behavior, you can either set it to true or explicitly pass `:authenticity_token => true` in form options. * Make possible to use a block in `button_to` helper if button text is hard to fit into the name parameter: ```ruby <%= button_to [:make_happy, @user] do %> Make happy <%= @user.name %> <% end %> # => "
" ``` * Replace `include_seconds` boolean argument with `:include_seconds => true` option in `distance_of_time_in_words` and `time_ago_in_words` signature. * Remove `button_to_function` and `link_to_function` helpers. * `truncate` now always returns an escaped HTML-safe string. The option `:escape` can be used as `false` to not escape the result. * `truncate` now accepts a block to show extra content when the text is truncated. * Add `week_field`, `week_field_tag`, `month_field`, `month_field_tag`, `datetime_local_field`, `datetime_local_field_tag`, `datetime_field` and `datetime_field_tag` helpers. * Add `color_field` and `color_field_tag` helpers. * Add `include_hidden` option to select tag. With `:include_hidden => false` select with multiple attribute doesn't generate hidden input with blank value. * Removed default size option from the `text_field`, `search_field`, `telephone_field`, `url_field`, `email_field` helpers. * Removed default cols and rows options from the `text_area` helper. * Adds `image_url`, `javascript_url`, `stylesheet_url`, `audio_url`, `video_url`, and `font_url` to assets tag helper. These URL helpers will return the full path to your assets. This is useful when you are going to reference this asset from external host. * Allow `value_method` and `text_method` arguments from `collection_select` and `options_from_collection_for_select` to receive an object that responds to `:call` such as a proc, to evaluate the option in the current element context. This works the same way with `collection_radio_buttons` and `collection_check_boxes`. * Add `date_field` and `date_field_tag` helpers which render an `input[type="date"]` tag. * Add `collection_check_boxes` form helper, similar to `collection_select`: ```ruby collection_check_boxes :post, :author_ids, Author.all, :id, :name # Outputs something like: ``` The label/check_box pairs can be customized with a block. * Add `collection_radio_buttons` form helper, similar to `collection_select`: ```ruby collection_radio_buttons :post, :author_id, Author.all, :id, :name # Outputs something like: ``` The label/radio_button pairs can be customized with a block. * `check_box` with an HTML5 attribute `:form` will now replicate the `:form` attribute to the hidden field as well. * label form helper accepts `:for => nil` to not generate the attribute. * Add `:format` option to `number_to_percentage`. * Add `config.action_view.logger` to configure logger for `Action View`. * `check_box` helper with `:disabled => true` will generate a `disabled` hidden field to conform with the HTML convention where disabled fields are not submitted with the form. This is a behavior change, previously the hidden tag had a value of the disabled checkbox. * `favicon_link_tag` helper will now use the favicon in `app/assets` by default. * `ActionView::Helpers::TextHelper#highlight` now defaults to the HTML5 `mark` element. #### Deprecations ### Sprockets Moved into a separate gem `sprockets-rails`. Active Record ------------- * Add `add_reference` and `remove_reference` schema statements. Aliases, `add_belongs_to` and `remove_belongs_to` are acceptable. References are reversible. ```ruby # Create a user_id column add_reference(:products, :user) # Create a supplier_id, supplier_type columns and appropriate index add_reference(:products, :supplier, polymorphic: true, index: true) # Remove polymorphic reference remove_reference(:products, :supplier, polymorphic: true) ``` * Add `:default` and `:null` options to `column_exists?`. ```ruby column_exists?(:testings, :taggable_id, :integer, null: false) column_exists?(:testings, :taggable_type, :string, default: 'Photo') ``` * `ActiveRecord::Relation#inspect` now makes it clear that you are dealing with a `Relation` object rather than an array: ```ruby User.where(:age => 30).inspect # =>