h2. Ruby on Rails 3.0 Release Notes
Rails 3.0 is ponies and rainbows! It's going to cook you dinner and fold your laundry. You're going to wonder how life was ever possible before it arrived. It's the Best Version of Rails We've Ever Done!
But seriously now, it's really good stuff. There are all the good ideas brought over from when the Merb team joined the party and brought a focus on framework agnosticism, slimmer and faster internals, and a handful of tasty APIs. If you're coming to Rails 3.0 from Merb 1.x, you should recognize lots. If you're coming from Rails 2.x, you're going to love it too.
Even if you don't give a hoot about any of our internal cleanups, Rails 3.0 is going to delight. We have a bunch of new features and improved APIs. It's never been a better time to be a Rails developer. Some of the highlights are:
* Brand new router with an emphasis on RESTful declarations
* New Action Mailer API modeled after Action Controller (now without the agonizing pain of sending multipart messages!)
* New Active Record chainable query language built on top of relational algebra
* Unobtrusive JavaScript helpers with drivers for Prototype, jQuery, and more coming (end of inline JS)
* Explicit dependency management with Bundler
On top of all that, we've tried our best to deprecate the old APIs with nice warnings. That means that you can move your existing application to Rails 3 without immediately rewriting all your old code to the latest best practices.
These release notes cover the major upgrades, but don't include every little bug fix and change. Rails 3.0 consists of almost 4,000 commits by more than 250 authors! If you want to see everything, check out the "list of commits":http://github.com/rails/rails/commits/master in the main Rails repository on GitHub.
endprologue.
WARNING: Rails 3.0 is currently in beta. This means that there are probably bugs and that you should "report them":http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/overview if you see them. You also may not want to run the NORAD nuclear launch application off a beta version. But if you're starting development on a new application and you don't mind getting wind in your hair, please do jump on board!
To install the last Rails 3 beta:
# Use sudo if your setup requires it
gem install rails --pre
h3. Upgrading to Rails 3
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 2.3.5 and make sure your application still runs as expected before attempting to update to Rails 3. Then take heed of the following changes:
h4. Rails 3 requires Ruby 1.8.7+
Rails 3.0 requires Ruby 1.8.7 or higher. Support for all of the previous Ruby versions has been dropped officially and you should upgrade as early as possible. Rails 3.0 is also compatible with Ruby 1.9.2.
h4. Rails Application object
As part of the groundwork for supporting running multiple Rails applications in the same process, Rails 3 introduces the concept of an Application object. An application object holds all the application specific configurations and is very similar in nature to +config/environment.rb+ from the previous versions of Rails.
Each Rails application now must have a corresponding application object. The application object is defined in +config/application.rb+. If you're upgrading an existing application to Rails 3, you must add this file and move the appropriate configurations from +config/environment.rb+ to +config/application.rb+.
h4. script/* replaced by script/rails
The new script/rails replaces all the scripts that used to be in the script directory. You do not run script/rails directly though, the +rails+ command detects it is being invoked in the root of a Rails application and runs the script for you. Intended usage is:
rails console # instead of script/console
rails g scaffold post title:string # instead of script/generate scaffold post title:string
Run rails --help for a list of all the options.
h4. Dependencies and config.gem
The +config.gem+ method is gone and has been replaced by using +bundler+ and a +Gemfile+, see "Vendoring Gems":#vendoring-gems below.
h4. Upgrade Process
To help with the upgrade process, a plugin named "Rails Upgrade":http://github.com/rails/rails_upgrade has been created to automate part of it.
Simply install the plugin, then run +rake rails:upgrade:check+ to check your app for pieces that need to be updated (with links to information on how to update them). It also offers a task to generate a +Gemfile+ based on your current +config.gem+ calls and a task to generate a new routes file from your current one. To get the plugin, simply run the following:
rails plugin install git://github.com/rails/rails_upgrade.git
You can see an example of how that works at "Rails Upgrade is now an Official Plugin":http://omgbloglol.com/post/364624593/rails-upgrade-is-now-an-official-plugin
Aside from Rails Upgrade tool, if you need more help, there are people on IRC and "rubyonrails-talk":http://groups.google.com/group/rubyonrails-talk that are probably doing the same thing, possibly hitting the same issues. Be sure to blog your own experiences when upgrading so others can benefit from your knowledge!
More information - "The Path to Rails 3: Approaching the upgrade":http://omgbloglol.com/post/353978923/the-path-to-rails-3-approaching-the-upgrade
h3. Creating a Rails 3.0 application
The new installing rails sequence (for the beta) is:
$ gem install rails --prerelease
$ rails myapp
$ cd myapp
h4. 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":http://github.com/carlhuda/bundler, 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 README on Github":http://github.com/carlhuda/bundler
h4. Living on the Edge
+Bundler+ and +Gemfile+ makes freezing your Rails application easy as pie with the new dedicated bundle command, so rake freeze is no longer relevant and has been dropped.
If you want to bundle straight from the Git repository, you can pass the +--edge+ flag:
$ rails 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/bin/rails myapp --dev
h3. Rails Architectural Changes
There are six major changes in the architecture of Rails.
h4. Railties Restrung
Railties was updated to provide a consistent plugin API for the entire Rails framework as well as a total rewrite of generators and the Rails bindings, the result is that developers can now hook into any significant stage of the generators and application framework in a consistent, defined manner.
h4. All Rails core components are decoupled
With the merge of Merb and Rails, one of the big jobs was to remove the tight coupling between Rails core components. This has now been achieved, and all Rails core components are now using the same API that you can use for developing plugins. This means any plugin you make, or any core component replacement (like DataMapper or Sequel) can access all the functionality that the Rails core components have access to and extend and enhance at will.
More information: - "The Great Decoupling":http://yehudakatz.com/2009/07/19/rails-3-the-great-decoupling/
h4. Active Model Abstraction
Part of decoupling the core components was extracting all ties to Active Record from Action Pack. This has now been completed. All new ORM plugins now just need to implement Active Model interfaces to work seamlessly with Action Pack.
More information: - "Make Any Ruby Object Feel Like ActiveRecord":http://yehudakatz.com/2010/01/10/activemodel-make-any-ruby-object-feel-like-activerecord/
h4. Controller Abstraction
Another big part of decoupling the core components was creating a base superclass that is separated from the notions of HTTP in order to handle rendering of views etc. This creation of +AbstractController+ allowed +ActionController+ and +ActionMailer+ to be greatly simplified with common code removed from all these libraries and put into Abstract Controller.
More Information: - "Rails Edge Architecture":http://yehudakatz.com/2009/06/11/rails-edge-architecture/
h4. Arel Integration
"Arel":http://github.com/brynary/arel (or Active Relation) has been taken on as the underpinnings of Active Record and is now required for Rails. Arel provides an SQL abstraction that simplifies out Active Record and provides the underpinnings for the relation functionality in Active Record.
More information: - "Why I wrote Arel":http://magicscalingsprinkles.wordpress.com/2010/01/28/why-i-wrote-arel/.
h4. Mail Extraction
Action Mailer ever since its beginnings has had monkey patches, pre parsers and even delivery and receiver agents, all in addition to having TMail vendored in the source tree. Version 3 changes that with all email message related functionality abstracted out to the "Mail":http://github.com/mikel/mail gem. This again reduces code duplication and helps create definable boundaries between Action Mailer and the email parser.
More information: - "New Action Mailer API in Rails 3":http://lindsaar.net/2010/1/26/new-actionmailer-api-in-rails-3
h3. Documentation
The documentation in the Rails tree is being updated with all the API changes, additionally, the "Rails Edge Guides":http://edgeguides.rubyonrails.org/ are being updated one by one to reflect the changes in Rails 3.0. The guides at "guides.rubyonrails.org":http://guides.rubyonrails.org/ however will continue to contain only the stable version of Rails (at this point, version 2.3.5, until 3.0 is released).
More Information: - "Rails Documentation Projects":http://weblog.rubyonrails.org/2009/1/15/rails-documentation-projects.
h3. Internationalization
A large amount of work has been done with I18n support in Rails 3, including the latest "I18n":http://github.com/svenfuchs/i18n gem supplying many speed improvements.
* I18n for any object - I18n behavior can be added to any object by including ActiveModel::Translation and ActiveModel::Validations. There is also an errors.messages fallback for translations.
* Attributes can have default translations.
* Form Submit Tags automatically pull the correct status (Create or Update) depending on the object status, and so pull the correct translation.
* Labels with I18n also now work by just passing the attribute name.
More Information: - "Rails 3 I18n changes":http://blog.plataformatec.com.br/2010/02/rails-3-i18n-changes/
h3. Railties
With the decoupling of the main Rails frameworks, Railties got a huge overhaul so as to make linking up frameworks, engines or plugins as painless and extensible as possible:
* Each application now has its own name space, application is started with YourAppName.boot for example, makes interacting with other applications a lot easier.
* Anything under Rails.root/app is now added to the load path, so you can make app/observers/user_observer.rb and Rails will load it without any modifications.
* Rails 3.0 now provides a Rails.config object, which provides a central repository of all sorts of Rails wide configuration options.
Application generation has received extra flags allowing you to skip the installation of test-unit, Active Record, Prototype and Git. Also a new --dev flag has been added which sets the application up with the +Gemfile+ pointing to your Rails checkout (which is determined by the path to the +rails+ binary). See rails --help for more info.
Railties generators got a huge amount of attention in Rails 3.0, basically:
* Generators were completely rewritten and are backwards incompatible.
* Rails templates API and generators API were merged (they are the same as the former).
* Generators are no longer loaded from special paths anymore, they are just found in the Ruby load path, so calling rails generate foo will look for generators/foo_generator.
* New generators provide hooks, so any template engine, ORM, test framework can easily hook in.
* New generators allow you to override the templates by placing a copy at Rails.root/lib/templates.
* Rails::Generators::TestCase is also supplied so you can create your own generators and test them.
Also, the views generated by Railties generators had some overhaul:
* Views now use +div+ tags instead of +p+ tags.
* Scaffolds generated now make use of _form partials, instead of duplicated code in the edit and new views.
* Scaffold forms now use f.submit which returns "Create ModelName" or "Update ModelName" depending on the state of the object passed in.
Finally a couple of enhancements were added to the rake tasks:
* rake db:forward was added, allowing you to roll forward your migrations individually or in groups.
* rake routes CONTROLLER=x was added allowing you to just view the routes for one controller.
Railties now deprecates:
* RAILS_ROOT in favour of Rails.root,
* RAILS_ENV in favour of Rails.env, and
* RAILS_DEFAULT_LOGGER in favour of Rails.logger.
PLUGIN/rails/tasks, and PLUGIN/tasks are no longer loaded all tasks now must be in PLUGIN/lib/tasks.
More information:
* "Discovering Rails 3 generators":http://blog.plataformatec.com.br/2010/01/discovering-rails-3-generators
* "Making Generators for Rails 3 with Thor":http://caffeinedd.com/guides/331-making-generators-for-rails-3-with-thor
* "The Rails Module (in Rails 3)":http://litanyagainstfear.com/blog/2010/02/03/the-rails-module/
h3. Action Pack
There have been significant internal and external changes in Action Pack.
h4. Abstract Controller
Abstract Controller pulls out the generic parts of Action Controller into a reusable module that any library can use to render templates, render partials, helpers, translations, logging, any part of the request response cycle. This abstraction allowed ActionMailer::Base to now just inherit from +AbstractController+ and just wrap the Rails DSL onto the Mail gem.
It also provided an opportunity to clean up Action Controller, abstracting out what could to simplify the code.
Note however that Abstract Controller is not a user facing API, you will not run into it in your day to day use of Rails.
More Information: - "Rails Edge Architecture":http://yehudakatz.com/2009/06/11/rails-edge-architecture/
h4. Action Controller
* application_controller.rb now has protect_from_forgery on by default.
* The cookie_verifier_secret has been deprecated and now instead it is assigned through Rails.application.config.cookie_secret and moved into its own file: config/initializers/cookie_verification_secret.rb.
* The session_store was configured in ActionController::Base.session, and that is now moved to Rails.application.config.session_store. Defaults are set up in config/initializers/session_store.rb.
* cookies.secure allowing you to set encrypted values in cookies with cookie.secure[:key] => value.
* cookies.permanent allowing you to set permanent values in the cookie hash cookie.permanent[:key] => value that raise exceptions on signed values if verification failures.
* You can now pass :notice => 'This is a flash message' or :alert => 'Something went wrong' to the format call inside a +respond_to+ block. The flash[] hash still works as previously.
* respond_with method has now been added to your controllers simplifying the venerable +format+ blocks.
* ActionController::Responder added allowing you flexibility in how your responses get generated.
Deprecations:
* filter_parameter_logging is deprecated in favour of config.filter_parameters << :password.
More Information:
* "Render Options in Rails 3":http://www.engineyard.com/blog/2010/render-options-in-rails-3/
* "Three reasons to love ActionController::Responder":http://weblog.rubyonrails.org/2009/8/31/three-reasons-love-responder
h4. Action Dispatch
Action Dispatch is new in Rails 3.0 and provides a new, cleaner implementation for routing.
* Big clean up and re-write of the router, the Rails router is now +rack_mount+ with a Rails DSL on top, it is a stand alone piece of software.
* Routes defined by each application are now name spaced within your Application module, that is:
# Instead of:
ActionController::Routing::Routes.draw do |map|
map.resources :posts
end
# You do:
AppName::Application.routes do
resources :posts
end
* Added +match+ method to the router, you can also pass any Rack application to the matched route.
* Added +constraints+ method to the router, allowing you to guard routers with defined constraints.
* Added +scope+ method to the router, allowing you to namespace routes for different languages or different actions, for example:
scope 'es' do
resources :projects, :path_names => { :edit => 'cambiar' }, :path => 'projeto'
end
# Gives you the edit action with /es/projeto/1/cambiar
* Added +root+ method to the router as a short cut for match '/', :to => path.
* You can pass optional segments into the match, for example match "/:controller(/:action(/:id))(.:format)", each parenthesized segment is optional.
* Routes can be expressed via blocks, for example you can call controller :home { match '/:action' }.
NOTE. The old style map commands still work as before with a backwards compatibility layer, however this will be removed in the 3.1 release.
Deprecations
* The catch all route for non-REST applications (/:controller/:action/:id) is now commented out.
* Routes :path_prefix no longer exists and :name_prefix now automatically adds "_" at the end of the given value.
More Information:
* "The Rails 3 Router: Rack it Up":http://yehudakatz.com/2009/12/26/the-rails-3-router-rack-it-up/
* "Revamped Routes in Rails 3":http://rizwanreza.com/2009/12/20/revamped-routes-in-rails-3
* "Generic Actions in Rails 3":http://yehudakatz.com/2009/12/20/generic-actions-in-rails-3/
h4. Action View
h5. Unobtrusive JavaScript
Major re-write was done in the Action View helpers, implementing Unobtrusive JavaScript (UJS) hooks and removing the old inline AJAX commands. This enables Rails to use any compliant UJS driver to implement the UJS hooks in the helpers.
What this means is that all previous remote_<method> helpers have been removed from Rails core and put into the "Prototype Legacy Helper":http://github.com/rails/prototype_legacy_helper. To get UJS hooks into your HTML, you now pass :remote => true instead. For example:
form_for @post, :remote => true
Produces: