Page and action caching are no longer available as part of ActionPack. The preference is now strongly for taking a Russian doll or fragment caching approach.
For an interesting analysis of the use of Russian doll caching see this Signal v. Noise post The Performance Impact of Russian Doll Caching
And for more on key based caching see this post How Key Based Cache Expiration Works
The Turbolinks gem has been introduce to speed up the users experience of the application. What Turbolinks does is to minimize the number of actual page loads by loading an HTML document once and then dynamically replacing the content of that page.
Turbolinks is included and enabled by default on all new projects in Rails 4.
Currently deprecated features will produce warnings in Rails 4.0 and will be removed entirely in Rails 4.1.
This is a significant change in the policy which previously had been more of a 'please don't use this anymore' policy.
The vendor/plugin
folder has reached its end of life point. It no longer exists in Rails 4.
Moving forward the Gemfile
should be used for dependency management. The behavior can be replicated, if that is absolutely necessary, by adding the code in question to the lib/directory
and manually initializing it in the config/directory
.
The default Rails welcome screen in new applications is now generated dynamically by an internal WelcomeController
.
It is no longer a static index.html
file in the public folder which must be cleaned up it. All one has to do to 'remove it' is to set a new root
route.
Rails 4 introduces the ActiveModel::Model
mixin. This allows PORO to take advantage of ActionPack methods and classes.
Active Model Models can take advantage of view helpers such as form_for
and the like they also gain access to
This is intended for use with data which should be modeled but does not need to be persisted.
A common use case for this is the classic contact form model. This is something which in most ways should behave like an ActiveRecord
model but does not require persistence.
In Rails 4 all scopes must be callables.
This aims to eliminate errors such as writing a non-callable scope which relies on dynamic data such as the current time.
Previously one might forgot to wrap such a scope in a lambda causing the time based information would be computed once, when the app is started, not when the scope is invoked as intended
During the initial boot of a Rails app in production the schema of the application's models is loaded into a schema cache.
In Rails 4 you can now create a dump of the schema which will then be used for this load in. This is especially useful for application with a large number of ActiveRecord
models.
Rails 4 allows for the specification of the isolation level for database transactions assuming that the underlying database supports isolation levels. PostgreSQL and MySQL both feature some support for isolation levels.
For more read the documentation for transaction isolation levels for PostgreSQL and MySQL
ActiveSupport
instrumentation now reports start and finish notifications to subscribers.
Rails 4 introduces the PATCH
HTTP verb. PATCH
replaces PUT
for update actions.
This is more proper in terms of REST semantics. Rails previously used the PUT
action for update which was not appropriate since only part of a given record is modified on an update whereas PUT
is for replacing a record altogether or creating a new record.
For the time being PUT
will continue to map to update actions as well as PATCH
.
The following have been extracted to gems
ActiveRecord::SessionStore
Most of these are deprecated, obsolete, or little used. Sprockets on the other hand has been extracted specifically so that its development and release cycle are no longer tied to that of the Rails core. Thereby allowing for more frequent and timely releases.
In one of the larger philosophical changes in Rails 4 mass assignment protection has moved from the model layer to the controller layer in Rails 4.
Previously of course attr_accessable
was used to control which of a model’s attributes could be mass assigned, i.e. via create, update, etc. methods.
In Rails 4 we now create a private method, by standard named model_params, which follows the pattern
def model_params
params.require(:model).permit(:attribute_1, :attribute_2,...)
end
this method is called in place of passing params[:model]
directly to a mass assigning method. It serves to strip out any forbidden attributes from the parameters passed.
To enforce this new system a ForbiddenAttributesProtection
module has been added which amongst other thing raises an error if you attempt to pass params[:model]
to one of the methods directly.
Routing Concerns have been added to the routing DSL. With concerns common sub-routes can be factored out of the routes they belong to. This helps in DRYing out routes.
The following slide features an example in an application with project and task models both of which can have comments.
MyApp::Application.routes.draw do
concern :commentable do
resources :comments
end
...
resources :projects, concerns: :commentable
resources :tasks, concerns: :commententable
...
end
Here the routing for comments has been extracted to the :commentable
concern. The sub-routes are made available through the concerns:
option on the resources routes.
Rails 4 allows you to add controller-level etags which will be part of the action etag
computation.
A common use case for this is to suffix an etag with an authorized user’s id thus ensuring that a cache containing sensitive information is only accessible by the authorized used the information belongs to.
The response
object now provides a stream
method which allows for the streaming of JSON objects, as well as other type of data, from a controller. The common use case for this, and why JSON in particular is frequently mentioned in conjunction with this addition, is the sending of server sent events.
With SSE the server can push messages out to connections. This allows for real time interactivity. Previously an area where Rails fell short and other frameworks such as Node.js excelled.
Attention must be paid to what type of app server your application will be running on. A fully concurrent server, such as Puma, is necessary to properly utilize streaming.
A thorough, if slightly biased, take on streaming is available here Why Live Streaming in Rails 4 is a Big Deal
For a closer look at how live streaming work in Rails 4 check out these slides
ActionView
has been decoupled from ActionController
and will be moved to a separate gem in Rails 4.1.
The match
action matcher for routes no longer serves as a catchall. When matching routes you must now specify which HTTP verb(s) you are targeting.
All Strings rendered in erb are now escaped by default unless wrapped with a call to raw
or html_safe
has been called.
There are three new headers which are now sent with every HTTP request.
X-Frame-Options
[ prevents clickjacking ]X-XSS-Protection
[ protects against script injection ]X-Content-Type-Options
[ prevents browser from opening one file type as another ]There are new/renamed test locations. These are test/models
, test/helpers
, test/controllers
, and test/mailers
.
These reflect the structure common to rspec test suites. This is a one case of taking a common practices and formalizing it as part of the framework.
All of an application's executables now live in the bin/
directory.
There is a new rake task rake rails:update:bin
which create the bin/bundle
, bin/rake
, and bin/rails
directories.
Just what it says on the tin. Rails 4 is threadsafe by default. This no longer needs to be specified in a configuration file.
Naturally it is up to the developer to insure that gems they use are also threadsafe.
You may no longer pass the -b or --builder switch to rails new. To achieve the same effect it is suggested that you use application templates instead.
config.thread_safe!
is now deprecated in favor of config.eager_load
. The latter provides better control over what is eager loaded.
Rails::Plugin
is no more, finally. The Gemfile
should be used for all ‘plugin’ management.
The Dalli gem replaces memcache-client in ActiveSupport::Cache::MemCacheStore
. Dalli is considerably faster.
ActiveSupport::Cache::Entry
has been optimized in both the memory and processing domains.
Inflections can now been defined on a per locale basis. singularize and pluralize now both take locale as an extra argument. (also the singular of police is no longer polouse)
Object#try
now returns nil
instead of raising a NoMethodError
if the receiving object does not implement the method. The previous behavior is available via the Object#try!
method.
String#to_date
now raises ArgumentError: invalid date
instead of NoMethodError: undefined method ‘div’ for nil:NilClass
when given an invalid date. It also behaves the same as Date.parse
and accepts more ‘invalid’ dates than Rails 3.
ActiveSupport::TestCase#pending
- Use skip
from MiniTest
ActiveSupport::Benchmarkable#silence
- Not threadsafe, to be rwor as of 4.1
ActiveSupport::JSON::Variable
- Define your own #to_json
and #encode_json
methods for custom JSON string literals
Module#local_constant_names
- Use Module@local_contants
instead
BufferedLogger
- Use ActiveSupport::Logger
or Ruby’s own logger instead
assert_present
and assert_blank
- Use object.present?
and object.blank?
#up
and #down
methods no longer required in migrations
drop_table
and remove_column
are now reversible
remove_columns
added for removing multiple columns (previously available through remove_column
). This is non-reversible
change_table
is now reversible so long as its block does not call: remove
, change
, or change_default
.
New reversible
method can specify code to be run when migrating up or down
New revert
method will revert an entire migration or a given block
Relation#load
added to explicitly load the record and return self.
Model.all
now, finally, returns a Relation
rather than an array of models.
New ActiveRecord::Migration.check_pending!
raises an error if migrations are pending.
ActiveRecord::Store
now allows you to specify a custom coder for encoding/decoding the store.
mysql
and mysql2
connections will now be set to strict mode by default.
Automatic EXPLAIN queries are no longer performed. active_record.auto_explain_threshold_in_seconds
is no longer used and should be removed from config.
New create_join_table
migration helper to create HABTM join tables.
PostgreSQL hstore records and array type supported.
There is now a not
query which can be inserted into where
chains in the query interface.
The Rails 2 era hash-based finder api is fully deprecated. Methods which previously accepted 'finder options' no longer do.
All dynamic finder methods except find_by_...()
and find_by_...!()
are deprecated.
The following slides indicate how they can be replaced.
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 find_or_initialize_by(...)
.
find_or_create_by_...
can be rewritten using find_or_create_by(...)
.
find_or_create_by_...!
can be rewritten using find_or_create_by!(...)
.
Much of the information here is taken from the Rails 4 Release Notes
Additional information was taken from Remarkable Labs Rails 4 Countdown. It is worth noting that their series of articles was written fairly early in the beta phase of Rails 4 and a number of the changes/features it mentions did not make into the final version of Rails 4.0.
The two most notable of these, which unsurprisingly are connected, are the ActiveSupport::Queue
class, which would introduce a native and lightweight way to run background jobs in Rails apps, and Asynchronous Action Mailer which would make use of the new queue and allow for asynchronous mailing without using a third-party gem.
Both of these are slated to be added in Rails 4.1. They were pushed back due to dissatisfaction with the current implementation rather than with the features themselves.