40 KiB
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 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 inconfig/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 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:
$ 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)
- Mass assignment protection in Active Record models (Github, Pull Request)
- ActiveRecord::SessionStore (Github, Pull Request)
- Active Record Observers (Github, Commit)
- Active Resource (Github, Pull Request, Blog)
- Action Caching (Github, Pull Request)
- Page Caching (Github, Pull Request)
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 byrake notes
andrake notes:custom
. -
New test locations
test/models
,test/helpers
,test/controllers
, andtest/mailers
. Corresponding rake tasks added as well. (Pull Request) -
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
andconfig.active_record.mass_assignment_sanitizer
from new applications since MassAssignmentSecurity has been extracted from Rails. -
Change
rails new
andrails 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 ofconfig.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 forreferences
/belongs_to
, for instancerails 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 asrake 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 defaultActiveSupport::ThreadedQueueConsumer
. -
Add
Rails.queue
for processing jobs in the background. -
Remove
Rack::SSL
in 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_for
inindex.html.erb
. -
Rails::Plugin
is 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::MissingTemplate
exception when no implicit template could be found. -
Asynchronously send messages via the Rails Queue. (Pull Request)
-
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
-
Allow for callbacks in mailers similar to ActionController::Base. You can now set up headers/attachments using
before_filter
orafter_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 toActionMailer::Base
instance methods likemessage
,attachments
,headers
.
Action Pack
Action Controller
-
Add
ActionController::Flash.add_flash_types
method to allow people to register their own flash types. e.g.:class ApplicationController add_flash_types :error, :warning end
If you add the above code, you can use
<%= error %>
in an erb, andredirect_to /foo, :error => 'message'
in a controller. -
Encrypted Cookies + Sign using Derived Keys. (Pull Request)
-
Remove Active Model dependency from Action Pack.
-
Support unicode characters in routes. Route will be automatically escaped, so instead of manually escaping:
get Rack::Utils.escape('こんにちは') => 'home#index'
You just have to write the unicode route:
get 'こんにちは' => 'home#index'
-
Return proper format on exceptions.
-
Extracted redirect logic from
ActionController::ForceSSL::ClassMethods.force_ssl
intoActionController::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
andrespond_with
now raiseActionController::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 ofapplication/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.class AccountsController < ApplicationController force_ssl :if => :ssl_configured? def ssl_configured? !Rails.env.development? end end
Deprecations
-
Deprecated
ActionController::Integration
in favour ofActionDispatch::Integration
. -
Deprecated
ActionController::IntegrationTest
in favour ofActionDispatch::IntegrationTest
. -
Deprecated
ActionController::PerformanceTest
in favour ofActionDispatch::PerformanceTest
. -
Deprecated
ActionController::AbstractRequest
in favour ofActionDispatch::Request
. -
Deprecated
ActionController::Request
in favour ofActionDispatch::Request
. -
Deprecated
ActionController::AbstractResponse
in favour ofActionDispatch::Response
. -
Deprecated
ActionController::Response
in favour ofActionDispatch::Response
. -
Deprecated
ActionController::Routing
in favour ofActionDispatch::Routing
.
Action Dispatch
-
Add Routing Concerns to declare common routes that can be reused inside others resources and routes.
Code before:
resources :messages do resources :comments end resources :posts do resources :comments resources :images, only: :index end
Code after:
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)
-
Include
mounted_helpers
(helpers for accessing mounted engines) inActionDispatch::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
, andassert_routing
all raiseAssertion
instead 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 newpatch
method, and understand:patch
in the existing places where a verb is configured, like:via
. Functional tests have a new methodpatch
and integration tests have a new methodpatch_via_redirect
. If:patch
is the default verb for updates, edits are tunneled asPATCH
rather than asPUT
and routing acts accordingly. -
Integration tests support the OPTIONS method.
-
expires_in
accepts amust_revalidate
flag. If true, "must-revalidate" is added to theCache-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 haveX-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) inActionView::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 ofdata-disable-with
option fromsubmit_tag
,button_tag
andbutton_to
helpers. -
Remove
:mouseover
option fromimage_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 togrouped_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
andtime_field_tag
helpers which render aninput[type="time"]
tag. -
Removed old
text_helper
apis forhighlight
,excerpt
andword_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:<%= button_to [:make_happy, @user] do %> Make happy <strong><%= @user.name %></strong> <% end %> # => "<form method="post" action="/users/1/make_happy" class="button_to"> # <div> # <button type="submit"> # Make happy <strong>Name</strong> # </button> # </div> # </form>"
-
Replace
include_seconds
boolean argument with:include_seconds => true
option indistance_of_time_in_words
andtime_ago_in_words
signature. -
Remove
button_to_function
andlink_to_function
helpers. -
truncate
now always returns an escaped HTML-safe string. The option:escape
can be used asfalse
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
anddatetime_field_tag
helpers. -
Add
color_field
andcolor_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
, andfont_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
andtext_method
arguments fromcollection_select
andoptions_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 withcollection_radio_buttons
andcollection_check_boxes
. -
Add
date_field
anddate_field_tag
helpers which render aninput[type="date"]
tag. -
Add
collection_check_boxes
form helper, similar tocollection_select
: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="" />
The label/check_box pairs can be customized with a block.
-
Add
collection_radio_buttons
form helper, similar tocollection_select
: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>
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 tonumber_to_percentage
. -
Add
config.action_view.logger
to configure logger forAction View
. -
check_box
helper with:disabled => true
will generate adisabled
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 inapp/assets
by default. -
ActionView::Helpers::TextHelper#highlight
now defaults to the HTML5mark
element.
Deprecations
Sprockets
Moved into a separate gem sprockets-rails
.
Active Record
-
Add
add_reference
andremove_reference
schema statements. Aliases,add_belongs_to
andremove_belongs_to
are 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
:default
and:null
options tocolumn_exists?
.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 aRelation
object rather than an array:User.where(:age => 30).inspect # => <ActiveRecord::Relation [#<User ...>, #<User ...>]> User.where(:age => 30).to_a.inspect # => [#<User ...>, #<User ...>]
if more than 10 items are returned by the relation, inspect will only show the first 10 followed by ellipsis.
-
Add
:collation
and:ctype
support 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 returnsfalse
with thefalse
argument. -
Added support for specifying the precision of a timestamp in the postgresql adapter. So, instead of having to incorrectly specify the precision using the
:limit
option, 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#pluck
to 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:
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
-
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_attributes
hash 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_messages
option 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#destroy
but will raise anActiveRecord::RecordNotDestroyed
exception 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#delete
for 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#from
to accept otherActiveRecord::Relation
objects. -
Added custom coders support for
ActiveRecord::Store
. Now you can set your custom coder like this:store :settings, accessors: [ :color, :homepage ], coder: JSON
-
mysql
andmysql2
connections will setSQL_MODE=STRICT_ALL_TABLES
by default to avoid silent data loss. This can be disabled by specifyingstrict: false
inconfig/database.yml
. (Pull Request) -
Added default order to
ActiveRecord::Base#first
to assure consistent results among different database engines. IntroducedActiveRecord::Base#take
as a replacement to the old behavior. -
Added an
:index
option to automatically create indexes forreferences
andbelongs_to
statements in migrations. This can be either a boolean or a hash that is identical to options available to theadd_index
method:create_table :messages do |t| t.references :person, :index => true end
Is the same as:
create_table :messages do |t| t.references :person end add_index :messages, :person_id
Generators have also been updated to use the new syntax.
-
Added bang methods for mutating
ActiveRecord::Relation
objects. For example, whilefoo.where(:bar)
will return a new object leaving foo unchanged,foo.where!(:bar)
will mutate the foo object. -
Added
#find_by
and#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#slice
to 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
SchemaCache
instance because we want to boot more quickly when we have many models. (Pull Request)# 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
PostgreSQL
adapter. -
The
add_index
method now supports awhere
option that receives a string with the partial index criteria. -
Added the
ActiveRecord::NullRelation
class implementing the null object pattern for the Relation class. -
Implemented
ActiveRecord::Relation#none
method which returns a chainable relation with zero records (an instance of theNullRelation
class). 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_table
migration 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
@attributes
hash 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:
Post.includes(:comments).where("comments.name = 'foo'")
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'").references(:comments)
Note that you do not need to explicitly specify references in the following cases, as they can be automatically inferred:
Post.where(comments: { name: 'foo' }) Post.where('comments.name' => 'foo') Post.order('comments.name')
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.
-
Support for the
schema_info
table 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.
-
PostgreSQL hstore records can be created.
-
PostgreSQL hstore types are automatically deserialized from the database.
-
Support for array datatype in PostgreSQL. (Pull Request)
-
Added
#update_columns
method which updates the attributes from the passed-in hash without calling save, hence skipping validations and callbacks.ActiveRecordError
will 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:find_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!
The implementation of the deprecated dynamic finders has been moved to the
active_record_deprecated_finders
gem. -
Deprecated the old-style hash based finder API. This means that methods which previously accepted "finder options" no longer do. For example this:
Post.find(:all, :conditions => { :comments_count => 10 }, :limit => 5)
should be rewritten in the new style which has existed since Rails 3:
Post.where(comments_count: 10).limit(5)
Note that as an interim step, it is possible to rewrite the above as:
Post.scoped(: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.
Calling
Post.scoped(options)
is a shortcut forPost.scoped.merge(options)
.Relation#merge
now 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::conditions becomes :where :include becomes :includes :extend becomes :extending
The code to implement the deprecated features has been moved out to the
active_record_deprecated_finders
gem. 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:
scope :red, where(color: 'red') default_scope where(color: 'red')
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 :recent, where(published_at: Time.now - 2.weeks)
Or a more subtle variant:
scope :recent, -> { where(published_at: Time.now - 2.weeks) } scope :recent_red, recent.where(color: 'red')
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 :remove_conditions, except(:where) where(...).remove_conditions # => still has conditions
-
Added deprecation for the
:dependent => :restrict
association option. -
Up until now
has_many
andhas_one, :dependent => :restrict
option raised aDeleteRestrictionError
at 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
DeleteRestrictionError
and then addconfig.active_record.dependent_restrict_raises = false
to your application config. -
New rails application would be generated with the
config.active_record.dependent_restrict_raises = false
in 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::SessionStore
is removed from Rails 4.0 and is now a separate gem.
Active Model
-
Changed
AM::Serializers::JSON.include_root_in_json
default 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
validates
will no longer enable the corresponding validators. -
ConfirmationValidator
error messages will attach to:#{attribute}_confirmation
instead ofattribute
. -
Added
ActiveModel::Model
, a mixin to make Ruby objects work with Action Pack out of the box. (Pull Request) -
ActiveModel::Errors#to_json
supports 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::NumberHelper
methods, to avoid errors with empty locales or missing values. -
Time#change
now works with time values with offsets other than UTC or the local time zone. -
Add
Time#prev_quarter
andTime#next_quarter
short-hands formonths_ago(3)
andmonths_since(3)
. -
Add
Time#last_week
,Time#last_month
,Time#last_year
as aliases forTime#prev_week
,Time#prev_month
, andTime#prev_year
. -
Add
Date#last_week
,Date#last_month
,Date#last_year
as aliases forDate#prev_week
,Date#prev_month
, andDate#prev_year
. -
Remove obsolete and unused
require_association
method from dependencies. -
Add
:instance_accessor
option 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::NumberHelper
methods have been moved toActiveSupport::NumberHelper
and are now available viaNumeric#to_s
. -
Numeric#to_s
now accepts the formatting options :phone, :currency, :percentage, :delimited, :rounded, :human, and :human_size. -
Add
Hash#transform_keys
,Hash#transform_keys!
,Hash#deep_transform_keys
andHash#deep_transform_keys!
. -
Changed xml type datetime to dateTime (with upper case letter T).
-
Add
:instance_accessor
option forclass_attribute
. -
constantize
now looks in the ancestor chain. -
Add
Hash#deep_stringify_keys
andHash#deep_stringify_keys!
to convert all keys from aHash
instance into strings. -
Add
Hash#deep_symbolize_keys
andHash#deep_symbolize_keys!
to convert all keys from aHash
instance into symbols. -
Object#try
can't call private methods. -
AS::Callbacks#run_callbacks remove key argument.
-
deep_dup
works more expectedly now and duplicates also values inHash
instances and elements inArray
instances. -
Inflector no longer applies ice -> ouse to words like slice, police.
-
Add
ActiveSupport::Deprecations.behavior = :silence
to completely ignore Rails runtime deprecations. -
Make
Module#delegate
stop using send - can no longer delegate to private methods. -
AS::Callbacks deprecate :rescuable option.
-
Adds
Integer#ordinal
to 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#pending
method, useskip
instead. -
Deletes the compatibility method
Module#method_names
, useModule#methods
from now on (which returns symbols). -
Deletes the compatibility method
Module#instance_method_names
, useModule#instance_methods
from now on (which returns symbols). -
Unicode database updated to 6.1.0.
-
Adds
encode_big_decimal_as_string
option 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#before
and#after
methods asaround
callback. -
BufferedLogger
is deprecated. UseActiveSupport::Logger
or thelogger
from Ruby stdlib. -
Deprecates the compatibility method
Module#local_constant_names
and useModule#local_constants
instead (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.