Ruby on Rails 4.0 Release Notes
sources:
https://github.com/rails/rails/blob/master/guides/source/4_0_release_notes.md
http://edgeguides.rubyonrails.org/4_0_release_notes.html
Ruby on Rails 4.0 Release Notes
Highlights in Rails 4.0: (WIP)
- Ruby 1.9.3 only
 - Strong Parameters
 - Queue API
 - Caching Improvements
 
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 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.0sass-rails ~> 3.2.3coffee-rails ~> 3.2.1uglifier >= 1.0.3
 
TODO: Update the versions above.
- Rails 4.0 removes 
vendor/pluginscompletely. 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 inconfig/initializers/my_plugin.rb. 
TODO: Configuration changes in environment files
Creating a Rails 4.0 application
<code> You should have the 'rails' rubygem installed $ rails new myapp $ cd myapp </code>
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 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
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:
<code>$ rails new myapp --edge </code>
If you have a local checkout of the Rails repository and want to generate an application using that, you can pass the —dev flag:
<code>$ ruby /path/to/rails/railties/bin/rails new myapp --dev </code>
Major Features
Documentation
- Guides are rewritten in GitHub Flavored Markdown.
 
Railties
- Allow scaffold/model/migration generators to accept a 
polymorphicmodifier forreferences/belongs_to, for instance<code>rails g model Product supplier:references{polymorphic} </code>will generate the model withbelongs_to :supplier, polymorphic: trueassociation and appropriate migration. - Set 
config.active_record.migration_errorto:page_loadfor development. - Add runner to 
Rails::Railtieas a hook called just after runner starts. - Add 
/rails/info/routespath which displays the same information asrake routes. - Improved 
rake routesoutput for redirects. - Load all environments available in 
config.paths["config/environments"]. - Add 
config.queue_consumerto allow the default consumer to be configurable. - Add 
Rails.queueas an interface with a default implementation that consumes jobs in a separate thread. - Remove 
Rack::SSLin favour ofActionDispatch::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.# 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 runningrails generate. - Scaffold now uses 
content_tag_forinindex.html.erb. Rails::Pluginis removed. Instead of adding plugins tovendor/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::MissingTemplateexception when no implicit template could be found. - Asynchronously send messages via the Rails Queue.
 - 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.
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 
Action Pack
Action Controller
- Add 
ActionController::Flash.add_flash_typesmethod to allow people to register their own flash types. e.g.:If you add the above code, you can useclass ApplicationController add_flash_types :error, :warning end
<%= error %>in an erb, andredirect_to /foo, :error => 'message'in a controller. - Remove Active Model dependency from Action Pack.
 - Support unicode characters in routes. Route will be automatically escaped, so instead of manually escaping:
You just have to write the unicode route:
get Rack::Utils.escape('こんにちは') => 'home#index'get 'こんにちは' => 'home#index'
 - Return proper format on exceptions.
 - Extracted redirect logic from 
ActionController::ForceSSL::ClassMethods.force_sslintoActionController::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_toandrespond_withnow raiseActionController::UnknownFormatinstead of directly returning head 406. The exception is rescued and converted to 406 in the exception handling middleware.- JSONP now uses 
application/javascriptinstead ofapplication/jsonas 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 
_methodhack). - For resources, both PATCH and PUT are routed to the 
updateaction. - Don’t ignore 
force_sslin development. This is a change of behavior - use an:ifcondition to recreate the old behavior.class AccountsController < ApplicationController force_ssl :if => :ssl_configured? def ssl_configured? !Rails.env.development? end end 
Deprecations
- Deprecated 
ActionController::Integrationin favour ofActionDispatch::Integration. - Deprecated 
ActionController::IntegrationTestin favour ofActionDispatch::IntegrationTest. - Deprecated 
ActionController::PerformanceTestin favour ofActionDispatch::PerformanceTest. - Deprecated 
ActionController::AbstractRequestin favour ofActionDispatch::Request. - Deprecated 
ActionController::Requestin favour ofActionDispatch::Request. - Deprecated 
ActionController::AbstractResponsein favour ofActionDispatch::Response. - Deprecated 
ActionController::Responsein favour ofActionDispatch::Response. - Deprecated 
ActionController::Routingin favour ofActionDispatch::Routing. 
Action Dispatch
- Add Routing Concerns to declare common routes that can be reused inside others resources and routes.Code before:
Code after:
resources :messages do resources :comments end resources :posts do resources :comments resources :images, only: :index end
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 
RoutingErrorin development. - Include 
mounted_helpers(helpers for accessing mounted engines) inActionDispatch::IntegrationTestby default. - Added 
ActionDispatch::SSLmiddleware 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,:hostand:port. - Allows 
assert_redirected_toto match against a regular expression. - Adds a backtrace to the routing error page in development.
 assert_generates,assert_recognizes, andassert_routingall raiseAssertioninstead ofRoutingError.- Allows the route helper root to take a string argument. For example, 
root 'pages#main'as a shortcut forroot to: 'pages#main'. - Adds support for the PATCH verb: Request objects respond to 
patch?. Routes now have a newpatchmethod, and understand:patchin the existing places where a verb is configured, like:via. Functional tests have a new methodpatchand integration tests have a new methodpatch_via_redirect. If:patchis the default verb for updates, edits are tunneled asPATCHrather than asPUTand routing acts accordingly. - Integration tests support the OPTIONS method.
 expires_inaccepts amust_revalidateflag. If true, “must-revalidate” is added to theCache-Controlheader.- Default responder will now always use your overridden block in 
respond_withto render your response. - Turn off verbose mode of 
rack-cache, we still haveX-Rack-Cacheto check that info. 
Deprecations
Action View
- Remove Active Model dependency from Action Pack.
 - Allow to use 
mounted_helpers(helpers for accessing mounted engines) inActionView::TestCase. - Make current object and counter (when it applies) variables accessible when rendering templates with 
:objector:collection. - Allow to lazy load 
default_form_builderby passing a string instead of a constant. - Add index method to 
FormBuilderclass. - Adds support for layouts when rendering a partial with a given collection.
 - Remove 
:disable_within favor ofdata-disable-withoption fromsubmit_tag,button_tagandbutton_tohelpers. - Remove 
:mouseoveroption fromimage_taghelper. - 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 
divideroption togrouped_options_for_selectto generate a separator optgroup automatically, and deprecate prompt as third argument, in favor of using an options hash. - Add 
time_fieldandtime_field_taghelpers which render aninput[type="time"]tag. - Removed old 
text_helperapis forhighlight,excerptandword_wrap. - Remove the leading \n added by textarea on 
assert_select. - Changed default value for 
config.action_view.embed_authenticity_token_in_remote_formsto 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 => truein form options. - Make possible to use a block in 
button_tohelper if button text is hard to fit into the name parameter:<%= button_to [:make_happy, @user] do %> Make happy <strong><%= @user.name %></strong> <% end %> # => "<form method="post" action="/users/1/make_happy"n" style="margin: 0px; padding: 0px; border: 0px; ">button_to"> # <div> # <button type="submit"> # Make happy <strong>Name</strong> # </button> # </div> # </form>"
 - Replace 
include_secondsboolean argument with:include_seconds => trueoption indistance_of_time_in_wordsandtime_ago_in_wordssignature. - Remove 
button_to_functionandlink_to_functionhelpers. truncatenow always returns an escaped HTML-safe string. The option:escapecan be used asfalseto not escape the result.truncatenow 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_fieldanddatetime_field_taghelpers. - Add 
color_fieldandcolor_field_taghelpers. - Add 
include_hiddenoption to select tag. With:include_hidden => falseselect 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_fieldhelpers. - Removed default cols and rows options from the 
text_areahelper. - Adds 
image_url,javascript_url,stylesheet_url,audio_url,video_url, andfont_urlto 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_methodandtext_methodarguments fromcollection_selectandoptions_from_collection_for_selectto receive an object that responds to:callsuch as a proc, to evaluate the option in the current element context. This works the same way withcollection_radio_buttonsandcollection_check_boxes. - Add 
date_fieldanddate_field_taghelpers which render aninput[type="date"]tag. - Add 
collection_check_boxesform helper, similar tocollection_select:The label/check_box pairs can be customized with a block.collection_check_boxes :post, :author_ids, Author.all, :id, :name # Outputs something like: <input id="post_author_ids_1" name="post[author_ids][]" type="checkbox" value="1" /> <label for="post_author_ids_1">D. Heinemeier Hansson</label> <input id="post_author_ids_2" name="post[author_ids][]" type="checkbox" value="2" /> <label for="post_author_ids_2">D. Thomas</label> <input name="post[author_ids][]" type="hidden" value="" />
 - Add 
collection_radio_buttonsform helper, similar tocollection_select:The label/radio_button pairs can be customized with a block.collection_radio_buttons :post, :author_id, Author.all, :id, :name # Outputs something like: <input id="post_author_id_1" name="post[author_id]" type="radio" value="1" /> <label for="post_author_id_1">D. Heinemeier Hansson</label> <input id="post_author_id_2" name="post[author_id]" type="radio" value="2" /> <label for="post_author_id_2">D. Thomas</label>
 check_boxwith an HTML5 attribute:formwill now replicate the:formattribute to the hidden field as well.- label form helper accepts 
:for => nilto not generate the attribute. - Add 
:formatoption tonumber_to_percentage. - Add 
config.action_view.loggerto configure logger forAction View. check_boxhelper with:disabled => truewill generate adisabledhidden 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_taghelper will now use the favicon inapp/assetsby default.ActionView::Helpers::TextHelper#highlightnow defaults to the HTML5markelement.
Deprecations
Sprockets
Moved into a separate gem sprockets-rails.
Active Record
- Add 
add_referenceandremove_referenceschema statements. Aliases,add_belongs_toandremove_belongs_toare acceptable. References are reversible.# 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 
:defaultand:nulloptions tocolumn_exists?.column_exists?(:testings, :taggable_id, :integer, null: false) column_exists?(:testings, :taggable_type, :string, default: 'Photo')
 ActiveRecord::Relation#inspectnow makes it clear that you are dealing with aRelationobject rather than an array:if more than 10 items are returned by the relation, inspect will only show the first 10 followed by ellipsis.User.where(:age => 30).inspect # => <ActiveRecord::Relation [#<User ...>, #<User ...>]> User.where(:age => 30).to_a.inspect # => [#<User ...>, #<User ...>]
- Add 
:collationand:ctypesupport to PostgreSQL. These are available for PostgreSQL 8.4 or later.development: adapter: postgresql host: localhost database: rails_development username: foo password: bar encoding: UTF8 collation: ja_JP.UTF8 ctype: ja_JP.UTF8
 FinderMethods#exists?now returnsfalsewith thefalseargument.- Added support for specifying the precision of a timestamp in the postgresql adapter. So, instead of having to incorrectly specify the precision using the 
:limitoption, you may use:precision, as intended. For example, in a migration:def change create_table :foobars do |t| t.timestamps :precision => 0 end end - Allow 
ActiveRecord::Relation#pluckto accept multiple columns. Returns an array of arrays containing the typecasted values:Person.pluck(:id, :name) # SELECT people.id, people.name FROM people # => [[1, 'David'], [2, 'Jeremy'], [3, 'Jose']]
 - Improve the derivation of HABTM join table name to take account of nesting. It now takes the table names of the two models, sorts them lexically and then joins them, stripping any common prefix from the second table name. Some examples:
<code>Top level models (Category <=> Product) Old: categories_products New: categories_products Top level models with a global table_name_prefix (Category <=> Product) Old: site_categories_products New: site_categories_products Nested models in a module without a table_name_prefix method (Admin::Category <=> Admin::Product) Old: categories_products New: categories_products Nested models in a module with a table_name_prefix method (Admin::Category <=> Admin::Product) Old: categories_products New: admin_categories_products Nested models in a parent model (Catalog::Category <=> Catalog::Product) Old: categories_products New: catalog_categories_products Nested models in different parent models (Catalog::Category <=> Content::Page) Old: categories_pages New: catalog_categories_content_pages </code>
 - Move HABTM validity checks to 
ActiveRecord::Reflection. One side effect of this is to move when the exceptions are raised from the point of declaration to when the association is built. This is consistant with other association validity checks. - Added 
stored_attributeshash which contains the attributes stored usingActiveRecord::Store. This allows you to retrieve the list of attributes you’ve defined.class User < ActiveRecord::Base store :settings, accessors: [:color, :homepage] end User.stored_attributes[:settings] # [:color, :homepage]
 - PostgreSQL default log level is now ‘warning’, to bypass the noisy notice messages. You can change the log level using the
min_messagesoption available in yourconfig/database.yml. - Add uuid datatype support to PostgreSQL adapter.
 - Added 
ActiveRecord::Migration.check_pending!that raises an error if migrations are pending. - Added 
#destroy!which acts like#destroybut will raise anActiveRecord::RecordNotDestroyedexception instead of returningfalse. - Allow blocks for count with 
ActiveRecord::Relation, to work similar asArray#count:Person.where("age > 26").count { |person| person.gender == 'female' } - Added support to 
CollectionAssociation#deletefor passing fixnum or string values as record ids. This finds the records responding to the ids and deletes them.class Person < ActiveRecord::Base has_many :pets end person.pets.delete("1") # => [#<Pet id: 1>] person.pets.delete(2, 3) # => [#<Pet id: 2>, #<Pet id: 3>] - It’s not possible anymore to destroy a model marked as read only.
 - Added ability to 
ActiveRecord::Relation#fromto accept otherActiveRecord::Relationobjects. - Added custom coders support for 
ActiveRecord::Store. Now you can set your custom coder like this:store :settings, accessors: [ :color, :homepage ], coder: JSON
 mysqlandmysql2connections will setSQL_MODE=STRICT_ALL_TABLESby default to avoid silent data loss. This can be disabled by specifyingstrict: falseinconfig/database.yml.- Added default order to 
ActiveRecord::Base#firstto assure consistent results among different database engines. IntroducedActiveRecord::Base#takeas a replacement to the old behavior. - Added an 
:indexoption to automatically create indexes forreferencesandbelongs_tostatements in migrations. This can be either a boolean or a hash that is identical to options available to theadd_indexmethod:Is the same as:create_table :messages do |t| t.references :person, :index => true end
Generators have also been updated to use the new syntax.create_table :messages do |t| t.references :person end add_index :messages, :person_id
 - Added bang methods for mutating 
ActiveRecord::Relationobjects. For example, whilefoo.where(:bar)will return a new object leaving foo unchanged,foo.where!(:bar)will mutate the foo object. - Added 
#find_byand#find_by!to mirror the functionality provided by dynamic finders in a way that allows dynamic input more easily:Post.find_by name: 'Spartacus', rating: 4 Post.find_by "published_at < ?", 2.weeks.ago Post.find_by! name: 'Spartacus'
 - Added 
ActiveRecord::Base#sliceto return a hash of the given methods with their names as keys and returned values as values. - Remove IdentityMap - IdentityMap has never graduated to be an “enabled-by-default” feature, due to some inconsistencies with associations, as described in this commit. Hence the removal from the codebase, until such issues are fixed.
 - Added a feature to dump/load internal state of 
SchemaCacheinstance because we want to boot more quickly when we have many models.# execute rake task. RAILS_ENV=production bundle exec rake db:schema:cache:dump => generate db/schema_cache.dump # add config.use_schema_cache_dump = true in config/production.rb. BTW, true is default. # boot rails. RAILS_ENV=production bundle exec rails server => use db/schema_cache.dump # If you remove clear dumped cache, execute rake task. RAILS_ENV=production bundle exec rake db:schema:cache:clear => remove db/schema_cache.dump
 - Added support for partial indices to 
PostgreSQLadapter. - The 
add_indexmethod now supports awhereoption that receives a string with the partial index criteria. - Added the 
ActiveRecord::NullRelationclass implementing the null object pattern for the Relation class. - Implemented 
ActiveRecord::Relation#nonemethod which returns a chainable relation with zero records (an instance of theNullRelationclass). Any subsequent condition chained to the returned relation will continue generating an empty relation and will not fire any query to the database. - Added 
create_join_tablemigration helper to create HABTM join tables.create_join_table :products, :categories # => # create_table :categories_products, :id => false do |td| # td.integer :product_id, :null => false # td.integer :category_id, :null => false # end
 - The primary key is always initialized in the 
@attributeshash to nil (unless another value has been specified). - In previous releases, the following would generate a single query with an OUTER JOIN comments, rather than two separate queries:
This behaviour relies on matching SQL string, which is an inherently flawed idea unless we write an SQL parser, which we do not wish to do. Therefore, it is now deprecated. To avoid deprecation warnings and for future compatibility, you must explicitly state which tables you reference, when using SQL snippets:
Post.includes(:comments).where("comments.name = 'foo'")Note that you do not need to explicitly specify references in the following cases, as they can be automatically inferred:Post.includes(:comments).where("comments.name = 'foo'").references(:comments)You also do not need to worry about this unless you are doing eager loading. Basically, don’t worry unless you see a deprecation warning or (in future releases) an SQL error due to a missing JOIN.Post.where(comments: { name: 'foo' }) Post.where('comments.name' => 'foo') Post.order('comments.name') - Support for the 
schema_infotable has been dropped. Please switch toschema_migrations. - Connections must be closed at the end of a thread. If not, your connection pool can fill and an exception will be raised.
 - Added the 
ActiveRecord::Modelmodule which can be included in a class as an alternative to inheriting fromActiveRecord::Base:class Post include ActiveRecord::Model end
 - PostgreSQL hstore records can be created.
 - PostgreSQL hstore types are automatically deserialized from the database.
 - Added 
#update_columnsmethod which updates the attributes from the passed-in hash without calling save, hence skipping validations and callbacks.ActiveRecordErrorwill be raised when called on new objects or when at least one of the attributes is marked as read only.post.attributes # => {"id"=>2, "title"=>"My title", "body"=>"My content", "author"=>"Peter"} post.update_columns({title: 'New title', author: 'Sebastian'}) # => true post.attributes # => {"id"=>2, "title"=>"New title", "body"=>"My content", "author"=>"Sebastian"} 
Deprecations
- Deprecated most of the ‘dynamic finder’ methods. All dynamic methods except for 
find_by_...andfind_by_...!are deprecated. Here’s how you can rewrite the code:The implementation of the deprecated dynamic finders has been moved to thefind_all_by_... can be rewritten using where(...) find_last_by_... can be rewritten using where(...).last scoped_by_... can be rewritten using where(...) find_or_initialize_by_... can be rewritten using where(...).first_or_initialize find_or_create_by_... can be rewritten using where(...).first_or_create find_or_create_by_...! can be rewritten using where(...).first_or_create!
active_record_deprecated_findersgem. - Deprecated the old-style hash based finder API. This means that methods which previously accepted “finder options” no longer do. For example this:
should be rewritten in the new style which has existed since Rails 3:
Post.find(:all, :conditions => { :comments_count => 10 }, :limit => 5)Note that as an interim step, it is possible to rewrite the above as:Post.where(comments_count: 10).limit(5)
This could save you a lot of work if there is a lot of old-style finder usage in your application. CallingPost.scoped(:where => { :comments_count => 10 }, :limit => 5)Post.scoped(options)is a shortcut forPost.scoped.merge(options).Relation#mergenow accepts a hash of options, but they must be identical to the names of the equivalent finder method. These are mostly identical to the old-style finder option names, except in the following cases:<code>:conditions becomes :where :include becomes :includes :extend becomes :extending </code>
The code to implement the deprecated features has been moved out to theactive_record_deprecated_findersgem. This gem is a dependency of Active Record in Rails 4.0. It will no longer be a dependency from Rails 4.1, but if your app relies on the deprecated features then you can add it to your own Gemfile. It will be maintained by the Rails core team until Rails 5.0 is released. - Deprecate eager-evaluated scopes.Don’t use this:
Use this:
scope :red, where(color: 'red') default_scope where(color: 'red')
The former has numerous issues. It is a common newbie gotcha to do the following:scope :red, -> { where(color: 'red') } default_scope { where(color: 'red') }Or a more subtle variant:scope :recent, where(published_at: Time.now - 2.weeks)
Eager scopes are also very complex to implement within Active Record, and there are still bugs. For example, the following does not do what you expect:scope :recent, -> { where(published_at: Time.now - 2.weeks) } scope :recent_red, recent.where(color: 'red')scope :remove_conditions, except(:where) where(...).remove_conditions # => still has conditions
 - Added deprecation for the 
:dependent => :restrictassociation option. - Up until now 
has_manyandhas_one, :dependent => :restrictoption raised aDeleteRestrictionErrorat the time of destroying the object. Instead, it will add an error on the model. - To fix this warning, make sure your code isn’t relying on a 
DeleteRestrictionErrorand then addconfig.active_record.dependent_restrict_raises = falseto your application config. - New rails application would be generated with the 
config.active_record.dependent_restrict_raises = falsein the application config. - The migration generator now creates a join table with (commented) indexes every time the migration name contains the word “join_table”.
 ActiveRecord::SessionStoreis removed from Rails 4.0 and is now a separate gem.
Active Model
- Changed 
AM::Serializers::JSON.include_root_in_jsondefault value to false. Now, AM Serializers and AR objects have the same default behaviour.class User < ActiveRecord::Base; end class Person include ActiveModel::Model include ActiveModel::AttributeMethods include ActiveModel::Serializers::JSON attr_accessor :name, :age def attributes instance_values end end user.as_json => {"id"=>1, "name"=>"Konata Izumi", "age"=>16, "awesome"=>true} # root is not included person.as_json => {"name"=>"Francesco", "age"=>22} # root is not included - Passing false hash values to 
validateswill no longer enable the corresponding validators. ConfirmationValidatorerror messages will attach to:#{attribute}_confirmationinstead ofattribute.- Added 
ActiveModel::Model, a mixin to make Ruby objects work with Action Pack out of the box. ActiveModel::Errors#to_jsonsupports a new parameter:full_messages.- Trims down the API by removing 
valid?anderrors.full_messages. 
Deprecations
Active Resource
- Active Resource is removed from Rails 4.0 and is now a separate gem.
 
Active Support
- Add default values to all 
ActiveSupport::NumberHelpermethods, to avoid errors with empty locales or missing values. Time#changenow works with time values with offsets other than UTC or the local time zone.- Add 
Time#prev_quarterandTime#next_quartershort-hands formonths_ago(3)andmonths_since(3). - Remove obsolete and unused 
require_associationmethod from dependencies. - Add 
:instance_accessoroption forconfig_accessor.class User include ActiveSupport::Configurable config_accessor :allowed_access, instance_accessor: false end User.new.allowed_access = true # => NoMethodError User.new.allowed_access # => NoMethodError
 ActionView::Helpers::NumberHelpermethods have been moved toActiveSupport::NumberHelperand are now available viaNumeric#to_s.Numeric#to_snow accepts the formatting options :phone, :currency, :percentage, :delimited, :rounded, :human, and :human_size.- Add 
Hash#transform_keys,Hash#transform_keys!,Hash#deep_transform_keysandHash#deep_transform_keys!. - Changed xml type datetime to dateTime (with upper case letter T).
 - Add 
:instance_accessoroption forclass_attribute. constantizenow looks in the ancestor chain.- Add 
Hash#deep_stringify_keysandHash#deep_stringify_keys!to convert all keys from aHashinstance into strings. - Add 
Hash#deep_symbolize_keysandHash#deep_symbolize_keys!to convert all keys from aHashinstance into symbols. Object#trycan’t call private methods.- AS::Callbacks#run_callbacks remove key argument.
 deep_dupworks more expectedly now and duplicates also values inHashinstances and elements inArrayinstances.- Inflector no longer applies ice -> ouse to words like slice, police.
 - Add 
ActiveSupport::Deprecations.behavior = :silenceto completely ignore Rails runtime deprecations. - Make 
Module#delegatestop using send - can no longer delegate to private methods. - AS::Callbacks deprecate :rescuable option.
 - Adds 
Integer#ordinalto get the ordinal suffix string of an integer. - AS::Callbacks :per_key option is no longer supported.
 - AS::Callbacks#define_callbacks add :skip_after_callbacks_if_terminated option.
 - Add html_escape_once to ERB::Util, and delegate escape_once tag helper to it.
 - Remove 
ActiveSupport::TestCase#pendingmethod, useskipinstead. - Deletes the compatibility method 
Module#method_names, useModule#methodsfrom now on (which returns symbols). - Deletes the compatibility method 
Module#instance_method_names, useModule#instance_methodsfrom now on (which returns symbols). - Unicode database updated to 6.1.0.
 - Adds 
encode_big_decimal_as_stringoption to force JSON serialization of BigDecimals as numeric instead of wrapping them in strings for safety. 
Deprecations
ActiveSupport::Callbacks: deprecate usage of filter object with#beforeand#aftermethods asaroundcallback.BufferedLoggeris deprecated. UseActiveSupport::Loggeror theloggerfrom Ruby stdlib.- Deprecates the compatibility method 
Module#local_constant_namesand useModule#local_constantsinstead (which returns symbols). 
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. Kudos to all of them.