On April 1st, Rails 3.0 Beta 2 was released, I thought I’d take this opportunity to highlight some of the changes between the Beta 1 and Beta 2 releases. According to GitHub, there are 2,691 new, unique commits – contributed by 244 authors – that were included in the Beta 2 release. I’ve picked some of the changes that I felt were important from the perspective of someone using Rails to build a web application and those that build plugins and other extensions for Rails.
The changes are separated by each of Rails’ individual components:
ActionMailer
You can now register interceptors and observers that will be called
before and after an email is sent, respectively. The interceptor object
must implement the delivering_email
method, while the
observer object must implement delivered_email
. Here’s a
simple example:
class MyInterceptor
def self.delivering_email(mail)
# do something before sending the email
end
end
class MyObserver
def self.delivered_email(mail)
# do something after sending the email
end
end
ActionMailer::Base.register_interceptor(MyInterceptor)
ActionMailer::Base.register_observer(MyObserver)
ActionPack
Block helpers now return Strings, so you can use <%= form_for
@foo do |f| %>
. <% form_for @foo do |f| %>
still works but will give you a deprecation notice.
The way that send_file
works has changed, it now defers to
a Rack middleware called Rack::Sendfile
. With that, the
following options have been removed from send_file
:
:stream
, :buffer_size
, and
:x_sendfile
. The header used to send the file is
configurable via config.action_dispatch.x_sendfile_header
– which defaults to “X-Sendfile” – , and servers can configure this
setting as well by setting the “X-Sendfile-Type” header. Hopefully,
hosting companies specializing in Rails deployments will set this
header, so that it will work transparently for those deploying there.
If you do need to set it manually, for say Lighttpd, here’s an example:
class MyApp < Rails::Application
config.action_dispatch.x_sendfile_header = 'X-Lighttpd-Send-File'
end
ActiveModel
For those creating libraries that they want to conform with ActiveModel,
there has been some changes to ActiveModel::Lint – a module of tests
that you can include in your tests to ensure your library conforms to
ActiveModel. #new_record?
and #destroyed?
were removed, use #persisted?
instead. For those of you
that are curious, ActiveRecord’s implementation of
persisted?
is as follows: A model is persisted if it’s not
a new_record?
and it was not destroyed?
.
In addition, #to_key
was added to ActiveModel::Lint, this
is used to generate DOM IDs for ActiveModel objects.
ActiveRecord
You can now prefix the table names all of the models in a module, you
just need to define self.table_name_prefix
on the module:
module Prefixed
def self.table_name_prefix
'prefixed_'
end
class ModelName < ActiveRecord::Base
end
end
ActiveSupport
There are new assertions you can use in your tests:
assert_blank
and assert_present
. Here they
are used in a simple example:
assert_blank [] # => true
assert_present {:data => 'x' } # => true
yajl-ruby
was added as a JSON parsing backend; and is the
preferred backend, if available. There was an interesting discussion
about using ActiveSupport::JSON.encode
over
#to_json
on the patch’s Lighthouse ticket.
Session store configuration has changed. The
cookie_verifier_secret
has been deprecated and it is now
assigned through Rails.application.config.cookie_secret
instead and moved into it’s own file:
initializers/cookie_verification_secret.rb
. Also,
session_store
configuration has also been changed from
ActionController::Base.session
to
Rails.application.config.session_store
and has been moved
to initializers/session_store.rb
.
If you were building a plugin that inherited from
Rails::Railtie
, you were probably setting
railtie_name
and/or engine_name
, well both of
them have been deprecated. You can now add any object to the
configuration object: config.your_plugin = {}
. To see how
the Rails internals switched to this new configuration approach, view the commit.