Rails 2.1 is now available for general consumption with all the features and fixes we’ve been putting in over the last six months since 2.0. This has been a huge effort by a very wide range of contributors helping to make it happen.
Over the past six months, we’ve had 1,400 contributors creating patches and vetting them. This has resulted in 1,600+ patches. A truly staggering number. And lots of that has made it into this release.
New features
The new major features are:
Thanks to Ryan Daigle for the feature introductions and Ryan Bates for the Railscasts. It makes writing the release notes so much easier :).
As always, you can install with:
gem install rails
...or you can use the Git tag for 2.1.0.
Enjoy!
Capistrano 2.4.0 is now available. Capistrano is the deployment tool of choice for many Rails programmers, but can be used for much more, allowing you to automate remote tasks using a simple task-oriented framework in Ruby.
Install it via RubyGems:
gem install capistrano
You can read the entire release announcement on Jamis Buck’s weblog.
Capistrano 2.4.0 is now available. Capistrano is the deployment tool of choice for many Rails programmers, but can be used for much more, allowing you to automate remote tasks using a simple task-oriented framework in Ruby.
Install it via RubyGems:
gem install capistrano
You can read the entire release announcement on Jamis Buck’s weblog.
Rails 2.1 is now available for general consumption with all the features and fixes we’ve been putting in over the last six months since 2.0. This has been a huge effort by a very wide range of contributors helping to make it happen.
Over the past six months, we’ve had 1,400 contributors creating patches and vetting them. This has resulted in 1,600+ patches. A truly staggering number. And lots of that has made it into this release.
New features
The new major features are:
Thanks to Ryan Daigle for the feature introductions and Ryan Bates for the Railscasts. It makes writing the release notes so much easier :).
As always, you can install with:
gem install rails
...or you can use the Git tag for 2.1.0.
Enjoy!
Threat level orange, guys! The release candidate for Rails 2.1 is drawing awfully close, so if you’ve been sitting on a patch that just must make it in now is the time to rise hell or high water to make it so. Once we cut the release candidate, we’ll be loathe to introduce anything but bug fixes to the features already there.
So get in your saddle, cowboy, and make that patch happen. Remember that the party has moved to Github and Lighthouse. Giddiyap!
Threat level orange, guys! The release candidate for Rails 2.1 is drawing awfully close, so if you’ve been sitting on a patch that just must make it in now is the time to rise hell or high water to make it so. Once we cut the release candidate, we’ll be loathe to introduce anything but bug fixes to the features already there.
So get in your saddle, cowboy, and make that patch happen. Remember that the party has moved to Github and Lighthouse. Giddiyap!
Capistrano is a utility for managing remote servers and automating remote tasks. It is popularly used to deploy Rails applications (but can do oh, so much more!). Version 2.2.0 is now available (well, it’s released, anyway, you might need to wait for the file to propagate to the gem mirrors).
gem install capistrano
Version 2.2.0 sports the following changes:
FEATURE: Dynamic role definition. The role() method now accepts a block, which should return either a host name, a Capistrano::ServerDefinition object, an array of host names, or an array of Capistrano::ServerDefinition objects. This can be used to describe the servers in a role at runtime.
role :app do hosts = some_method_that_looks_up_the_current_hosts hosts[0,3] end
FEATURE: Alternative server-centric role definitions, using the server() method:
role :app, "server" role :web, "server" # the above is the same as this: server "server", :app, :web
FEATURE: Support for a :max_hosts option in tasks, that restricts the task so that it is only executed in <max_hosts> hosts at a time, in chunks. This helps people who use Capistrano with very large numbers of servers, and prevents them running into connection caps and from running out of memory.
task :ping, :max_hosts => 100 do # anything here will only run against 100 hosts at a time end # alternatively, you can pass :max_hosts to the run command itself for # finer granularity task :pong do # this will run on ALL hosts at once run "something" # this will run on no more than 100 hosts at a time run "something-else", :max_hosts => 100 end
ENHANCEMENT: Improved Git support!
ENHANCEMENT: Password prompt support in the Mercurial SCM.
ENHANCEMENT: Implement Bzr#next_revision so that pending changes can be reported correctly, and use checkout—lightweight instead of branch.
ENHANCEMENT: Bring back the :p4sync_flags and :p4client_root variables for perforce SCM.
Additionally, there are several minor bugs and typos that have been fixed. You can see the CHANGELOG for all the gory details.
As ever, please report bugs via the Rails trac, at http://dev.rubyonrails.org. And if you aren’t yet subscribed to the Capistrano mailing list, it’s where all the cool cappists hang out.
Capistrano is a utility for managing remote servers and automating remote tasks. It is popularly used to deploy Rails applications (but can do oh, so much more!). Version 2.2.0 is now available (well, it’s released, anyway, you might need to wait for the file to propagate to the gem mirrors).
gem install capistrano
Version 2.2.0 sports the following changes:
FEATURE: Dynamic role definition. The role() method now accepts a block, which should return either a host name, a Capistrano::ServerDefinition object, an array of host names, or an array of Capistrano::ServerDefinition objects. This can be used to describe the servers in a role at runtime.
role :app do hosts = some_method_that_looks_up_the_current_hosts hosts[0,3] end
FEATURE: Alternative server-centric role definitions, using the server() method:
role :app, "server" role :web, "server" # the above is the same as this: server "server", :app, :web
FEATURE: Support for a :max_hosts option in tasks, that restricts the task so that it is only executed in <max_hosts> hosts at a time, in chunks. This helps people who use Capistrano with very large numbers of servers, and prevents them running into connection caps and from running out of memory.
task :ping, :max_hosts => 100 do # anything here will only run against 100 hosts at a time end # alternatively, you can pass :max_hosts to the run command itself for # finer granularity task :pong do # this will run on ALL hosts at once run "something" # this will run on no more than 100 hosts at a time run "something-else", :max_hosts => 100 end
ENHANCEMENT: Improved Git support!
ENHANCEMENT: Password prompt support in the Mercurial SCM.
ENHANCEMENT: Implement Bzr#next_revision so that pending changes can be reported correctly, and use checkout—lightweight instead of branch.
ENHANCEMENT: Bring back the :p4sync_flags and :p4client_root variables for perforce SCM.
Additionally, there are several minor bugs and typos that have been fixed. You can see the CHANGELOG for all the gory details.
As ever, please report bugs via the Rails trac, at http://dev.rubyonrails.org. And if you aren’t yet subscribed to the Capistrano mailing list, it’s where all the cool cappists hang out.
ActiveMerchant 1.3 has been released. The focus on this latest release was the addition of standardized support for the Address Verification System (AVS) and credit card verification value (CVV2) checks across all gateways which is the latest extraction from Shopify.
AVS information helps reduce fraud by checking the billing address of the customer with the cardholder information on file at the credit card company. CVV2 checks help ensure that the cardholder information has not been stolen from a database of credit card numbers because it is forbidden to record or store CVV2 numbers in any way.
The results of the AVS and CVV2 checks are now available in the response object. ActiveMerchant does all the work of interpreting the information returned from the payment gateways for you and makes the information available in a consistent hash format.
Sample AVS/CVV2 result:
response.avs_result['message'] #=>
"Street address and 9-digit postal code match."
response.cvv_result['message'] #=>
"Suspicious Transaction."
# Details:
response.avs_result['code'] #=> "X"
response.avs_result['street_match'] #=> "Y"
response.avs_result['postal_match'] #=> "Y"
response.cvv_result['code'] #=> "D"
Other notable improvements with the 1.3 release include:
Coinciding with the 1.3 release of ActiveMerchant is the ActiveMerchant PeepCode PDF by Cody Fauser. The PDF goes over the basics of payment processing, making purchases with ActiveMerchant, and security considerations to keep in mind when processing credit cards in your Rails application. The PDF also walks through the development of a sample Rails application that addresses topics such as order pipelines, order state management and the appropriate unit testing a financial application requires. It is definitely a great read if you are curious about payment processing or require payment processing in your application.
ActiveMerchant 1.3 has been released. The focus on this latest release was the addition of standardized support for the Address Verification System (AVS) and credit card verification value (CVV2) checks across all gateways which is the latest extraction from Shopify.
AVS information helps reduce fraud by checking the billing address of the customer with the cardholder information on file at the credit card company. CVV2 checks help ensure that the cardholder information has not been stolen from a database of credit card numbers because it is forbidden to record or store CVV2 numbers in any way.
The results of the AVS and CVV2 checks are now available in the response object. ActiveMerchant does all the work of interpreting the information returned from the payment gateways for you and makes the information available in a consistent hash format.
Sample AVS/CVV2 result:
response.avs_result['message'] #=>
"Street address and 9-digit postal code match."
response.cvv_result['message'] #=>
"Suspicious Transaction."
# Details:
response.avs_result['code'] #=> "X"
response.avs_result['street_match'] #=> "Y"
response.avs_result['postal_match'] #=> "Y"
response.cvv_result['code'] #=> "D"
Other notable improvements with the 1.3 release include:
Coinciding with the 1.3 release of ActiveMerchant is the ActiveMerchant PeepCode PDF by Cody Fauser. The PDF goes over the basics of payment processing, making purchases with ActiveMerchant, and security considerations to keep in mind when processing credit cards in your Rails application. The PDF also walks through the development of a sample Rails application that addresses topics such as order pipelines, order state management and the appropriate unit testing a financial application requires. It is definitely a great read if you are curious about payment processing or require payment processing in your application.
Rails 2.0 is finally finished after about a year in the making. This is a fantastic release that’s absolutely stuffed with great new features, loads of fixes, and an incredible amount of polish. We’ve even taken a fair bit of cruft out to make the whole package more coherent and lean.
What a milestone for Ruby on Rails as well. I’ve personally been working on this framework for about four and a half years and we have contributors who’ve been around for almost as long as well. It’s really satisfying to see how far we’ve come in that period of time. That we’ve proven the initial hype worthy, that we’ve been able to stick with it and continue to push the envelope.
Before jumping into the breakdown of features, I’d just like to extend my deep gratitude towards everyone who helped make this release possible. From the stable of merry men in the Rails core to the hundreds of contributors who got a patch applied to everyone who participated in the community over the year. This release is a triumph for large-scale open source development and you can all be mighty proud of the role you played. Cheers!
With the touchy-feely stuff out of the way, let’s dig into the feast and look at just a sliver of what’s new:
Rails 2.0 is finally finished after about a year in the making. This is a fantastic release that’s absolutely stuffed with great new features, loads of fixes, and an incredible amount of polish. We’ve even taken a fair bit of cruft out to make the whole package more coherent and lean.
What a milestone for Ruby on Rails as well. I’ve personally been working on this framework for about four and a half years and we have contributors who’ve been around for almost as long as well. It’s really satisfying to see how far we’ve come in that period of time. That we’ve proven the initial hype worthy, that we’ve been able to stick with it and continue to push the envelope.
Before jumping into the breakdown of features, I’d just like to extend my deep gratitude towards everyone who helped make this release possible. From the stable of merry men in the Rails core to the hundreds of contributors who got a patch applied to everyone who participated in the community over the year. This release is a triumph for large-scale open source development and you can all be mighty proud of the role you played. Cheers!
With the touchy-feely stuff out of the way, let’s dig into the feast and look at just a sliver of what’s new:
Action Pack: Resources
This is where the bulk of the action for 2.0 has gone. We’ve got a slew of improvements to the RESTful lifestyle. First, we’ve dropped the semicolon for custom methods instead of the regular slash. So /people/1;edit is now /people/1/edit. We’ve also added the namespace feature to routing resources that makes it really easy to confine things like admin interfaces:
map.namespace(:admin) do |admin|
admin.resources :products,
:collection => { :inventory => :get },
:member => { :duplicate => :post },
:has_many => [ :tags, :images, :variants ]
end
Which will give you named routes like inventory_admin_products_url and admin_product_tags_url. To keep track of this named routes proliferation, we’ve added the “rake routes” task, which will list all the named routes created by routes.rb.
We’ve also instigated a new convention that all resource-based controllers will be plural by default. This allows a single resource to be mapped in multiple contexts and still refer to the same controller. Example:
# /avatars/45 => AvatarsController#show
map.resources :avatars
# /people/5/avatar => AvatarsController#show
map.resources :people, :has_one => :avatar
Action Pack: Multiview
Alongside the improvements for resources come improvements for multiview. We already have #respond_to, but we’ve taken it a step further and made it dig into the templates. We’ve separated the format of the template from its rendering engine. So show.rhtml now becomes show.html.erb, which is the template that’ll be rendered by default for a show action that has declared format.html in its respond_to. And you can now have something like show.csv.erb, which targets text/csv, but also uses the default ERB renderer.
So the new format for templates is action.format.renderer. A few examples:
Speaking of the iPhone, we’ve made it easier to declare “fake” types that are only used for internal routing. Like when you want a special HTML interface just for an iPhone. All it takes is something like this:
# should go in config/initializers/mime_types.rb
Mime.register_alias "text/html", :iphone
class ApplicationController < ActionController::Base
before_filter :adjust_format_for_iphone
private
def adjust_format_for_iphone
if request.env["HTTP_USER_AGENT"] && request.env["HTTP_USER_AGENT"][/(iPhone|iPod)/]
request.format = :iphone
end
end
end
class PostsController < ApplicationController
def index
respond_to do |format|
format.html # renders index.html.erb
format.iphone # renders index.iphone.erb
end
end
end
You’re encouraged to declare your own mime-type aliases in the config/initializers/mime_types.rb file. This file is included by default in all new applications.
Action Pack: Record identification
Piggy-backing off the new drive for resources are a number of simplifications for controller and view methods that deal with URLs. We’ve added a number of conventions for turning model classes into resource routes on the fly. Examples:
# person is a Person object, which by convention will
# be mapped to person_url for lookup
redirect_to(person)
link_to(person.name, person)
form_for(person)
Action Pack: HTTP Loving
As you might have gathered, Action Pack in Rails 2.0 is all about getting closer with HTTP and all its glory. Resources, multiple representations, but there’s more. We’ve added a new module to work with HTTP Basic Authentication, which turns out to be a great way to do API authentication over SSL. It’s terribly simple to use. Here’s an example (there are more in ActionController::HttpAuthentication):
class PostsController < ApplicationController
USER_NAME, PASSWORD = "dhh", "secret"
before_filter :authenticate, :except => [ :index ]
def index
render :text => "Everyone can see me!"
end
def edit
render :text => "I'm only accessible if you know the password"
end
private
def authenticate
authenticate_or_request_with_http_basic do |user_name, password|
user_name == USER_NAME && password == PASSWORD
end
end
end
We’ve also made it much easier to structure your JavaScript and stylesheet files in logical units without getting clobbered by the HTTP overhead of requesting a bazillion files. Using javascript_include_tag(:all, :cache => true) will turn public/javascripts/.js into a single public/javascripts/all.js file in production, while still keeping the files separate in development, so you can work iteratively without clearing the cache.
Along the same lines, we’ve added the option to cheat browsers who don’t feel like pipelining requests on their own. If you set ActionController::Base.asset_host = “assets%d.example.com”, we’ll automatically distribute your asset calls (like image_tag) to asset1 through asset4. That allows the browser to open many more connections at a time and increases the perceived speed of your application.
Action Pack: Security
Making it even easier to create secure applications out of the box is always a pleasure and with Rails 2.0 we’re doing it from a number of fronts. Most importantly, we now ship we a built-in mechanism for dealing with CRSF attacks. By including a special token in all forms and Ajax requests, you can guard from having requests made from outside of your application. All this is turned on by default in new Rails 2.0 applications and you can very easily turn it on in your existing applications using ActionController::Base.protect_from_forgery (see ActionController::RequestForgeryProtection for more).
We’ve also made it easier to deal with XSS attacks while still allowing users to embed HTML in your pages. The old TextHelper#sanitize method has gone from a black list (very hard to keep secure) approach to a white list approach. If you’re already using sanitize, you’ll automatically be granted better protection. You can tweak the tags that are allowed by default with sanitize as well. See TextHelper#sanitize for details.
Finally, we’ve added support for HTTP only cookies. They are not yet supported by all browsers, but you can use them where they are.
Action Pack: Exception handling
Lots of common exceptions would do better to be rescued at a shared level rather than per action. This has always been possible by overwriting rescue_action_in_public, but then you had to roll out your own case statement and call super. Bah. So now we have a class level macro called rescue_from, which you can use to declaratively point certain exceptions to a given action. Example:
class PostsController < ApplicationController
rescue_from User::NotAuthorized, :with => :deny_access
protected
def deny_access
...
end
end
Action Pack: Cookie store sessions
The default session store in Rails 2.0 is now a cookie-based one. That means sessions are no longer stored on the file system or in the database, but kept by the client in a hashed form that can’t be forged. This makes it not only a lot faster than traditional session stores, but also makes it zero maintenance. There’s no cron job needed to clear out the sessions and your server won’t crash because you forgot and suddenly had 500K files in tmp/session.
This setup works great if you follow best practices and keep session usage to a minimum, such as the common case of just storing a user_id and a the flash. If, however, you are planning on storing the nuclear launch codes in the session, the default cookie store is a bad deal. While they can’t be forged (so is_admin = true is fine), their content can be seen. If that’s a problem for your application, you can always just switch back to one of the traditional session stores (but first investigate that requirement as a code smell).
Action Pack: New request profiler
Figuring out where your bottlenecks are with real usage can be tough, but we just made it a whole lot easier with the new request profiler that can follow an entire usage script and report on the aggregate findings. You use it like this:
$ cat login_session.rb
get_with_redirect '/'
say "GET / => #{path}"
post_with_redirect '/sessions', :username => 'john', :password => 'doe'
say "POST /sessions => #{path}"
$ ./script/performance/request -n 10 login_session.rb
And you get a thorough breakdown in HTML and text on where time was spent and you’ll have a good idea on where to look for speeding up the application.
Action Pack: Miscellaneous
Also of note is AtomFeedHelper, which makes it even simpler to create Atom feeds using an enhanced Builder syntax. Simple example:
# index.atom.builder:
atom_feed do |feed|
feed.title("My great blog!")
feed.updated((@posts.first.created_at))
for post in @posts
feed.entry(post) do |entry|
entry.title(post.title)
entry.content(post.body, :type => 'html')
entry.author do |author|
author.name("DHH")
end
end
end
end
We’ve made a number of performance improvements, so asset tag calls are now much cheaper and we’re caching simple named routes, making them much faster too.
Finally, we’ve kicked out in_place_editor and autocomplete_for into plugins that live on the official Rails SVN.
Active Record: Performance
Active Record has seen a gazillion fixes and small tweaks, but it’s somewhat light on big new features. Something new that we have added, though, is a very simple Query Cache, which will recognize similar SQL calls from within the same request and return the cached result. This is especially nice for N+1 situations that might be hard to handle with :include or other mechanisms. We’ve also drastically improved the performance of fixtures, which makes most test suites based on normal fixture use be 50-100% faster.
Active Record: Sexy migrations
There’s a new alternative format for declaring migrations in a slightly more efficient format. Before you’d write:
create_table :people do |t|
t.column, "account_id", :integer
t.column, "first_name", :string, :null => false
t.column, "last_name", :string, :null => false
t.column, "description", :text
t.column, "created_at", :datetime
t.column, "updated_at", :datetime
end
Now you can write:
create_table :people do |t|
t.integer :account_id
t.string :first_name, :last_name, :null => false
t.text :description
t.timestamps
end
Active Record: Foxy fixtures
The fixtures in Active Record has taken a fair amount of flak lately. One of the key points in that criticism has been the work with declaring dependencies between fixtures. Having to relate fixtures through the ids of their primary keys is no fun. That’s been addressed now and you can write fixtures like this:
# sellers.yml
shopify:
name: Shopify
# products.yml
pimp_cup:
seller: shopify
name: Pimp cup
As you can see, it’s no longer necessary to declare the ids of the fixtures and instead of using seller_id to refer to the relationship, you just use seller and the name of the fixture.
Active Record: XML in, JSON out
Active Record has supported serialization to XML for a while. In 2.0 we’ve added deserialization too, so you can say Person.new.from_xml(“<person><name>David</name></person>“) and get what you’d expect. We’ve also added serialization to JSON, which supports the same syntax as XML serialization (including nested associations). Just do person.to_json and you’re ready to roll.
Active Record: Shedding some weight
To make Active Record a little leaner and meaner, we’ve removed the acts_as_XYZ features and put them into individual plugins on the Rails SVN repository. So say you’re using acts_as_list, you just need to do ./script/plugin install acts_as_list and everything will move along like nothing ever happened.
A little more drastic, we’ve also pushed all the commercial database adapters into their own gems. So Rails now only ships with adapters for MySQL, SQLite, and PostgreSQL. These are the databases that we have easy and willing access to test on. But that doesn’t mean the commercial databases are left out in the cold. Rather, they’ve now been set free to have an independent release schedule from the main Rails distribution. And that’s probably a good thing as the commercial databases tend to require a lot more exceptions and hoop jumping on a regular basis to work well.
The commercial database adapters now live in gems that all follow the same naming convention: activerecord-XYZ-adapter. So if you gem install activerecord-oracle-adapter, you’ll instantly have Oracle available as an adapter choice in all the Rails applications on that machine. You won’t have to change a single line in your applications to take use of it.
That also means it’ll be easier for new database adapters to gain traction in the Rails world. As long as you package your adapter according to the published conventions, users just have to install the gem and they’re ready to roll.
Active Record: with_scope with a dash of syntactic vinegar
ActiveRecord::Base.with_scope has gone protected to discourage people from misusing it in controllers (especially in filters). Instead, it’s now encouraged that you only use it within the model itself. That’s what it was designed for and where it logically remains a good fit. But of course, this is all about encouraging and discouraging. If you’ve weighed the pros and the cons and still want to use with_scope outside of the model, you can always call it through .send(:with_scope).
ActionWebService out, ActiveResource in
It’ll probably come as no surprise that Rails has picked a side in the SOAP vs REST debate. Unless you absolutely have to use SOAP for integration purposes, we strongly discourage you from doing so. As a naturally extension of that, we’ve pulled ActionWebService from the default bundle. It’s only a gem install actionwebservice away, but it sends an important message none the less.
At the same time, we’ve pulled the new ActiveResource framework out of beta and into the default bundle. ActiveResource is like ActiveRecord, but for resources. It follows a similar API and is configured to Just Work with Rails applications using the resource-driven approach. For example, a vanilla scaffold will be accessible by ActiveResource.
ActiveSupport
There’s not all that much new in ActiveSupport. We’ve a host of new methods like Array#rand for getting a random element from an array, Hash#except to filter down a hash from undesired keys and lots of extensions for Date. We also made testing a little nicer with assert_difference. Short of that, it’s pretty much just fixes and tweaks.
Action Mailer
This is a very modest update for Action Mailer. Besides a handful of bug fixes, we’ve added the option to register alternative template engines and assert_emails to the testing suite, which works like this:
Rails: The debugger is back
To tie it all together, we have a stream of improvements for Rails in general. My favorite amongst these is the return of the breakpoint in form of the debugger. It’s a real debugger too, not just an IRB dump. You can step back and forth, list your current position, and much more. It’s all coming from the gracious note of the ruby-debug gem. So you’ll have to install that for the new debugger to work.
To use the debugger, you just install the gem, put “debugger” somewhere in your application, and then start the server with—debugger or -u. When the code executes the debugger command, you’ll have it available straight in the terminal running the server. No need for script/breakpointer or anything else. You can use the debugger in your tests too.
Rails: Clean up your environment
Before Rails 2.0, config/environment.rb files every where would be clogged with all sorts of one-off configuration details. Now you can gather those elements in self-contained files and put them under config/initializers and they’ll automatically be loaded. New Rails 2.0 applications ship with two examples in form of inflections.rb (for your own pluralization rules) and mime_types.rb (for your own mime types). This should ensure that you need to keep nothing but the default in config/environment.rb.
Rails: Easier plugin order
Now that we’ve yanked out a fair amount of stuff from Rails and into plugins, you might well have other plugins that depend on this functionality. This can require that you load, say, acts_as_list before your own acts_as_extra_cool_list plugin in order for the latter to extend the former.
Before, this required that you named all your plugins in config.plugins. Major hassle when all you wanted to say was “I only care about acts_as_list being loaded before everything else”. Now you can do exactly that with config.plugins = [ :acts_as_list, :all ].
And hundreds upon hundreds of other improvements
What I’ve talked about above is but a tiny sliver of the full 2.0 package. We’ve got literally hundreds of bug fixes, tweaks, and feature enhancements crammed into Rails 2.0. All this coming off the work of tons of eager contributors working tirelessly to improve the framework in small, but important ways.
I encourage you to scourger the CHANGELOGs and learn more about all that changed.
So how do I upgrade?
If you want to move your application to Rails 2.0, you should first move it to Rails 1.2.6. That’ll include deprecation warnings for most everything we yanked out in 2.0. So if your application runs fine on 1.2.6 with no deprecation warnings, there’s a good chance that it’ll run straight up on 2.0. Of course, if you’re using, say, pagination, you’ll need to install the classic_pagination plugin. If you’re using Oracle, you’ll need to install the activerecord-oracle-adapter gem. And so on and so forth for all the extractions.
So how do I install?
To install through gems, do:
gem install rails -y
...if you’re having trouble with that (gem not found), just grab gems from our own repository in the meanwhile:
gem install rails -y --source http://gems.rubyonrails.org
To try it from an SVN tag, use (you may need to run this command twice depending on your current Rails version):
rake rails:freeze:edge TAG=rel_2-0-1
Note: It’s 2.0.1 because we found a small issue just after we pushed 2.0.0.
Now that we have the big Rails 2.0 release out the door, it’s a lot easier to push out smaller updates more frequently. So that’s what we’re going to do. Rails 2.0.2 contains a bunch of smaller fixes to various bugs, no show-stopping action, just further polish. But it also contains a few new defaults.
Now that we have the big Rails 2.0 release out the door, it’s a lot easier to push out smaller updates more frequently. So that’s what we’re going to do. Rails 2.0.2 contains a bunch of smaller fixes to various bugs, no show-stopping action, just further polish. But it also contains a few new defaults.
SQLite3 is the new default database
Most importantly is SQLite3 as the new database we’ll configure for by default when you run the rails generation command without any specification. This change comes as SQLite3 is simply an easier out of the box experience than MySQL. There’s no fussing with GRANTs and creates, the database is just there. This is especially so under OS X 10.5 Leopard, which ships with SQLite3 and the driver gems preinstalled as part of the development kit.
If you want to preconfigure your database for MySQL (or any of the other adapters), you simply do “rails -d mysql myapp” and everything is the same as before. But if you’re just playing with a new application or building a smallish internal tool, then I strongly recommend having a look at SQLite3. Thanks to the agnostic db/schema.rb, it’s as easy as changing your config/database.yml to switch from SQLite3 to MySQL (or another database) as soon as your load warrants it.
Don’t check for template changes in production mode
New applications will be generated with the following option in their config/environments/production.rb:
config.action_view.cache_template_loading = true
This will stop Rails from constantly doing STAT calls to the file system to check if the file has changed. This can make for a lot of I/O activity, especially if you have lots of partials. If you have very fast disks, this may not matter, but if you’re running off slower disks it can make quite a big difference.
The drawback is that you can no longer just svnup a single template file and see it changed immediately. You’ll have to restart the application servers to make that happen.
Regardless, we feel that this is the better default in a partial-heavy world, but you’re of course always free to change it.
Rails 2.0.2 is a drop-in replacement for Rails 2.0
To upgrade, just do “gem install rails” (if the gems are still not propagated, use—source http://gems.rubyonrails.org) or use the new rel_2-0-2 tag.
The rest of the changes are as follows:
Action Pack
ActionController::Base.asset_host = Proc.new { |source| if source.starts_with?(’/images’) “http://images.example.com” else “http://assets.example.com” end }
Active Record
Active Resource
Active Support
Rails
Now that we have the big Rails 2.0 release out the door, it’s a lot easier to push out smaller updates more frequently. So that’s what we’re going to do. Rails 2.0.2 contains a bunch of smaller fixes to various bugs, no show-stopping action, just further polish. But it also contains a few new defaults.
Now that we have the big Rails 2.0 release out the door, it’s a lot easier to push out smaller updates more frequently. So that’s what we’re going to do. Rails 2.0.2 contains a bunch of smaller fixes to various bugs, no show-stopping action, just further polish. But it also contains a few new defaults.
SQLite3 is the new default database
Most importantly is SQLite3 as the new database we’ll configure for by default when you run the rails generation command without any specification. This change comes as SQLite3 is simply an easier out of the box experience than MySQL. There’s no fussing with GRANTs and creates, the database is just there. This is especially so under OS X 10.5 Leopard, which ships with SQLite3 and the driver gems preinstalled as part of the development kit.
If you want to preconfigure your database for MySQL (or any of the other adapters), you simply do “rails -d mysql myapp” and everything is the same as before. But if you’re just playing with a new application or building a smallish internal tool, then I strongly recommend having a look at SQLite3. Thanks to the agnostic db/schema.rb, it’s as easy as changing your config/database.yml to switch from SQLite3 to MySQL (or another database) as soon as your load warrants it.
Don’t check for template changes in production mode
New applications will be generated with the following option in their config/environments/production.rb:
config.action_view.cache_template_loading = true
This will stop Rails from constantly doing STAT calls to the file system to check if the file has changed. This can make for a lot of I/O activity, especially if you have lots of partials. If you have very fast disks, this may not matter, but if you’re running off slower disks it can make quite a big difference.
The drawback is that you can no longer just svnup a single template file and see it changed immediately. You’ll have to restart the application servers to make that happen.
Regardless, we feel that this is the better default in a partial-heavy world, but you’re of course always free to change it.
Rails 2.0.2 is a drop-in replacement for Rails 2.0
To upgrade, just do “gem install rails” (if the gems are still not propagated, use—source http://gems.rubyonrails.org) or use the new rel_2-0-2 tag.
The rest of the changes are as follows:
Action Pack
ActionController::Base.asset_host = Proc.new { |source| if source.starts_with?(’/images’) “http://images.example.com” else “http://assets.example.com” end }
Active Record
Active Resource
Active Support
Rails
Rails 2.0 is finally finished after about a year in the making. This is a fantastic release that’s absolutely stuffed with great new features, loads of fixes, and an incredible amount of polish. We’ve even taken a fair bit of cruft out to make the whole package more coherent and lean.
What a milestone for Ruby on Rails as well. I’ve personally been working on this framework for about four and a half years and we have contributors who’ve been around for almost as long as well. It’s really satisfying to see how far we’ve come in that period of time. That we’ve proven the initial hype worthy, that we’ve been able to stick with it and continue to push the envelope.
Before jumping into the breakdown of features, I’d just like to extend my deep gratitude towards everyone who helped make this release possible. From the stable of merry men in the Rails core to the hundreds of contributors who got a patch applied to everyone who participated in the community over the year. This release is a triumph for large-scale open source development and you can all be mighty proud of the role you played. Cheers!
With the touchy-feely stuff out of the way, let’s dig into the feast and look at just a sliver of what’s new:
Rails 2.0 is finally finished after about a year in the making. This is a fantastic release that’s absolutely stuffed with great new features, loads of fixes, and an incredible amount of polish. We’ve even taken a fair bit of cruft out to make the whole package more coherent and lean.
What a milestone for Ruby on Rails as well. I’ve personally been working on this framework for about four and a half years and we have contributors who’ve been around for almost as long as well. It’s really satisfying to see how far we’ve come in that period of time. That we’ve proven the initial hype worthy, that we’ve been able to stick with it and continue to push the envelope.
Before jumping into the breakdown of features, I’d just like to extend my deep gratitude towards everyone who helped make this release possible. From the stable of merry men in the Rails core to the hundreds of contributors who got a patch applied to everyone who participated in the community over the year. This release is a triumph for large-scale open source development and you can all be mighty proud of the role you played. Cheers!
With the touchy-feely stuff out of the way, let’s dig into the feast and look at just a sliver of what’s new:
Action Pack: Resources
This is where the bulk of the action for 2.0 has gone. We’ve got a slew of improvements to the RESTful lifestyle. First, we’ve dropped the semicolon for custom methods instead of the regular slash. So /people/1;edit is now /people/1/edit. We’ve also added the namespace feature to routing resources that makes it really easy to confine things like admin interfaces:
map.namespace(:admin) do |admin|
admin.resources :products,
:collection => { :inventory => :get },
:member => { :duplicate => :post },
:has_many => [ :tags, :images, :variants ]
end
Which will give you named routes like inventory_admin_products_url and admin_product_tags_url. To keep track of this named routes proliferation, we’ve added the “rake routes” task, which will list all the named routes created by routes.rb.
We’ve also instigated a new convention that all resource-based controllers will be plural by default. This allows a single resource to be mapped in multiple contexts and still refer to the same controller. Example:
# /avatars/45 => AvatarsController#show
map.resources :avatars
# /people/5/avatar => AvatarsController#show
map.resources :people, :has_one => :avatar
Action Pack: Multiview
Alongside the improvements for resources come improvements for multiview. We already have #respond_to, but we’ve taken it a step further and made it dig into the templates. We’ve separated the format of the template from its rendering engine. So show.rhtml now becomes show.html.erb, which is the template that’ll be rendered by default for a show action that has declared format.html in its respond_to. And you can now have something like show.csv.erb, which targets text/csv, but also uses the default ERB renderer.
So the new format for templates is action.format.renderer. A few examples:
Speaking of the iPhone, we’ve made it easier to declare “fake” types that are only used for internal routing. Like when you want a special HTML interface just for an iPhone. All it takes is something like this:
# should go in config/initializers/mime_types.rb
Mime.register_alias "text/html", :iphone
class ApplicationController < ActionController::Base
before_filter :adjust_format_for_iphone
private
def adjust_format_for_iphone
if request.env["HTTP_USER_AGENT"] && request.env["HTTP_USER_AGENT"][/(iPhone|iPod)/]
request.format = :iphone
end
end
end
class PostsController < ApplicationController
def index
respond_to do |format|
format.html # renders index.html.erb
format.iphone # renders index.iphone.erb
end
end
end
You’re encouraged to declare your own mime-type aliases in the config/initializers/mime_types.rb file. This file is included by default in all new applications.
Action Pack: Record identification
Piggy-backing off the new drive for resources are a number of simplifications for controller and view methods that deal with URLs. We’ve added a number of conventions for turning model classes into resource routes on the fly. Examples:
# person is a Person object, which by convention will
# be mapped to person_url for lookup
redirect_to(person)
link_to(person.name, person)
form_for(person)
Action Pack: HTTP Loving
As you might have gathered, Action Pack in Rails 2.0 is all about getting closer with HTTP and all its glory. Resources, multiple representations, but there’s more. We’ve added a new module to work with HTTP Basic Authentication, which turns out to be a great way to do API authentication over SSL. It’s terribly simple to use. Here’s an example (there are more in ActionController::HttpAuthentication):
class PostsController < ApplicationController
USER_NAME, PASSWORD = "dhh", "secret"
before_filter :authenticate, :except => [ :index ]
def index
render :text => "Everyone can see me!"
end
def edit
render :text => "I'm only accessible if you know the password"
end
private
def authenticate
authenticate_or_request_with_http_basic do |user_name, password|
user_name == USER_NAME && password == PASSWORD
end
end
end
We’ve also made it much easier to structure your JavaScript and stylesheet files in logical units without getting clobbered by the HTTP overhead of requesting a bazillion files. Using javascript_include_tag(:all, :cache => true) will turn public/javascripts/.js into a single public/javascripts/all.js file in production, while still keeping the files separate in development, so you can work iteratively without clearing the cache.
Along the same lines, we’ve added the option to cheat browsers who don’t feel like pipelining requests on their own. If you set ActionController::Base.asset_host = “assets%d.example.com”, we’ll automatically distribute your asset calls (like image_tag) to asset1 through asset4. That allows the browser to open many more connections at a time and increases the perceived speed of your application.
Action Pack: Security
Making it even easier to create secure applications out of the box is always a pleasure and with Rails 2.0 we’re doing it from a number of fronts. Most importantly, we now ship we a built-in mechanism for dealing with CRSF attacks. By including a special token in all forms and Ajax requests, you can guard from having requests made from outside of your application. All this is turned on by default in new Rails 2.0 applications and you can very easily turn it on in your existing applications using ActionController::Base.protect_from_forgery (see ActionController::RequestForgeryProtection for more).
We’ve also made it easier to deal with XSS attacks while still allowing users to embed HTML in your pages. The old TextHelper#sanitize method has gone from a black list (very hard to keep secure) approach to a white list approach. If you’re already using sanitize, you’ll automatically be granted better protection. You can tweak the tags that are allowed by default with sanitize as well. See TextHelper#sanitize for details.
Finally, we’ve added support for HTTP only cookies. They are not yet supported by all browsers, but you can use them where they are.
Action Pack: Exception handling
Lots of common exceptions would do better to be rescued at a shared level rather than per action. This has always been possible by overwriting rescue_action_in_public, but then you had to roll out your own case statement and call super. Bah. So now we have a class level macro called rescue_from, which you can use to declaratively point certain exceptions to a given action. Example:
class PostsController < ApplicationController
rescue_from User::NotAuthorized, :with => :deny_access
protected
def deny_access
...
end
end
Action Pack: Cookie store sessions
The default session store in Rails 2.0 is now a cookie-based one. That means sessions are no longer stored on the file system or in the database, but kept by the client in a hashed form that can’t be forged. This makes it not only a lot faster than traditional session stores, but also makes it zero maintenance. There’s no cron job needed to clear out the sessions and your server won’t crash because you forgot and suddenly had 500K files in tmp/session.
This setup works great if you follow best practices and keep session usage to a minimum, such as the common case of just storing a user_id and a the flash. If, however, you are planning on storing the nuclear launch codes in the session, the default cookie store is a bad deal. While they can’t be forged (so is_admin = true is fine), their content can be seen. If that’s a problem for your application, you can always just switch back to one of the traditional session stores (but first investigate that requirement as a code smell).
Action Pack: New request profiler
Figuring out where your bottlenecks are with real usage can be tough, but we just made it a whole lot easier with the new request profiler that can follow an entire usage script and report on the aggregate findings. You use it like this:
$ cat login_session.rb
get_with_redirect '/'
say "GET / => #{path}"
post_with_redirect '/sessions', :username => 'john', :password => 'doe'
say "POST /sessions => #{path}"
$ ./script/performance/request -n 10 login_session.rb
And you get a thorough breakdown in HTML and text on where time was spent and you’ll have a good idea on where to look for speeding up the application.
Action Pack: Miscellaneous
Also of note is AtomFeedHelper, which makes it even simpler to create Atom feeds using an enhanced Builder syntax. Simple example:
# index.atom.builder:
atom_feed do |feed|
feed.title("My great blog!")
feed.updated((@posts.first.created_at))
for post in @posts
feed.entry(post) do |entry|
entry.title(post.title)
entry.content(post.body, :type => 'html')
entry.author do |author|
author.name("DHH")
end
end
end
end
We’ve made a number of performance improvements, so asset tag calls are now much cheaper and we’re caching simple named routes, making them much faster too.
Finally, we’ve kicked out in_place_editor and autocomplete_for into plugins that live on the official Rails SVN.
Active Record: Performance
Active Record has seen a gazillion fixes and small tweaks, but it’s somewhat light on big new features. Something new that we have added, though, is a very simple Query Cache, which will recognize similar SQL calls from within the same request and return the cached result. This is especially nice for N+1 situations that might be hard to handle with :include or other mechanisms. We’ve also drastically improved the performance of fixtures, which makes most test suites based on normal fixture use be 50-100% faster.
Active Record: Sexy migrations
There’s a new alternative format for declaring migrations in a slightly more efficient format. Before you’d write:
create_table :people do |t|
t.column, "account_id", :integer
t.column, "first_name", :string, :null => false
t.column, "last_name", :string, :null => false
t.column, "description", :text
t.column, "created_at", :datetime
t.column, "updated_at", :datetime
end
Now you can write:
create_table :people do |t|
t.integer :account_id
t.string :first_name, :last_name, :null => false
t.text :description
t.timestamps
end
Active Record: Foxy fixtures
The fixtures in Active Record has taken a fair amount of flak lately. One of the key points in that criticism has been the work with declaring dependencies between fixtures. Having to relate fixtures through the ids of their primary keys is no fun. That’s been addressed now and you can write fixtures like this:
# sellers.yml
shopify:
name: Shopify
# products.yml
pimp_cup:
seller: shopify
name: Pimp cup
As you can see, it’s no longer necessary to declare the ids of the fixtures and instead of using seller_id to refer to the relationship, you just use seller and the name of the fixture.
Active Record: XML in, JSON out
Active Record has supported serialization to XML for a while. In 2.0 we’ve added deserialization too, so you can say Person.new.from_xml(“<person><name>David</name></person>“) and get what you’d expect. We’ve also added serialization to JSON, which supports the same syntax as XML serialization (including nested associations). Just do person.to_json and you’re ready to roll.
Active Record: Shedding some weight
To make Active Record a little leaner and meaner, we’ve removed the acts_as_XYZ features and put them into individual plugins on the Rails SVN repository. So say you’re using acts_as_list, you just need to do ./script/plugin install acts_as_list and everything will move along like nothing ever happened.
A little more drastic, we’ve also pushed all the commercial database adapters into their own gems. So Rails now only ships with adapters for MySQL, SQLite, and PostgreSQL. These are the databases that we have easy and willing access to test on. But that doesn’t mean the commercial databases are left out in the cold. Rather, they’ve now been set free to have an independent release schedule from the main Rails distribution. And that’s probably a good thing as the commercial databases tend to require a lot more exceptions and hoop jumping on a regular basis to work well.
The commercial database adapters now live in gems that all follow the same naming convention: activerecord-XYZ-adapter. So if you gem install activerecord-oracle-adapter, you’ll instantly have Oracle available as an adapter choice in all the Rails applications on that machine. You won’t have to change a single line in your applications to take use of it.
That also means it’ll be easier for new database adapters to gain traction in the Rails world. As long as you package your adapter according to the published conventions, users just have to install the gem and they’re ready to roll.
Active Record: with_scope with a dash of syntactic vinegar
ActiveRecord::Base.with_scope has gone protected to discourage people from misusing it in controllers (especially in filters). Instead, it’s now encouraged that you only use it within the model itself. That’s what it was designed for and where it logically remains a good fit. But of course, this is all about encouraging and discouraging. If you’ve weighed the pros and the cons and still want to use with_scope outside of the model, you can always call it through .send(:with_scope).
ActionWebService out, ActiveResource in
It’ll probably come as no surprise that Rails has picked a side in the SOAP vs REST debate. Unless you absolutely have to use SOAP for integration purposes, we strongly discourage you from doing so. As a naturally extension of that, we’ve pulled ActionWebService from the default bundle. It’s only a gem install actionwebservice away, but it sends an important message none the less.
At the same time, we’ve pulled the new ActiveResource framework out of beta and into the default bundle. ActiveResource is like ActiveRecord, but for resources. It follows a similar API and is configured to Just Work with Rails applications using the resource-driven approach. For example, a vanilla scaffold will be accessible by ActiveResource.
ActiveSupport
There’s not all that much new in ActiveSupport. We’ve a host of new methods like Array#rand for getting a random element from an array, Hash#except to filter down a hash from undesired keys and lots of extensions for Date. We also made testing a little nicer with assert_difference. Short of that, it’s pretty much just fixes and tweaks.
Action Mailer
This is a very modest update for Action Mailer. Besides a handful of bug fixes, we’ve added the option to register alternative template engines and assert_emails to the testing suite, which works like this:
Rails: The debugger is back
To tie it all together, we have a stream of improvements for Rails in general. My favorite amongst these is the return of the breakpoint in form of the debugger. It’s a real debugger too, not just an IRB dump. You can step back and forth, list your current position, and much more. It’s all coming from the gracious note of the ruby-debug gem. So you’ll have to install that for the new debugger to work.
To use the debugger, you just install the gem, put “debugger” somewhere in your application, and then start the server with—debugger or -u. When the code executes the debugger command, you’ll have it available straight in the terminal running the server. No need for script/breakpointer or anything else. You can use the debugger in your tests too.
Rails: Clean up your environment
Before Rails 2.0, config/environment.rb files every where would be clogged with all sorts of one-off configuration details. Now you can gather those elements in self-contained files and put them under config/initializers and they’ll automatically be loaded. New Rails 2.0 applications ship with two examples in form of inflections.rb (for your own pluralization rules) and mime_types.rb (for your own mime types). This should ensure that you need to keep nothing but the default in config/environment.rb.
Rails: Easier plugin order
Now that we’ve yanked out a fair amount of stuff from Rails and into plugins, you might well have other plugins that depend on this functionality. This can require that you load, say, acts_as_list before your own acts_as_extra_cool_list plugin in order for the latter to extend the former.
Before, this required that you named all your plugins in config.plugins. Major hassle when all you wanted to say was “I only care about acts_as_list being loaded before everything else”. Now you can do exactly that with config.plugins = [ :acts_as_list, :all ].
And hundreds upon hundreds of other improvements
What I’ve talked about above is but a tiny sliver of the full 2.0 package. We’ve got literally hundreds of bug fixes, tweaks, and feature enhancements crammed into Rails 2.0. All this coming off the work of tons of eager contributors working tirelessly to improve the framework in small, but important ways.
I encourage you to scourger the CHANGELOGs and learn more about all that changed.
So how do I upgrade?
If you want to move your application to Rails 2.0, you should first move it to Rails 1.2.6. That’ll include deprecation warnings for most everything we yanked out in 2.0. So if your application runs fine on 1.2.6 with no deprecation warnings, there’s a good chance that it’ll run straight up on 2.0. Of course, if you’re using, say, pagination, you’ll need to install the classic_pagination plugin. If you’re using Oracle, you’ll need to install the activerecord-oracle-adapter gem. And so on and so forth for all the extractions.
So how do I install?
To install through gems, do:
gem install rails -y
...if you’re having trouble with that (gem not found), just grab gems from our own repository in the meanwhile:
gem install rails -y --source http://gems.rubyonrails.org
To try it from an SVN tag, use (you may need to run this command twice depending on your current Rails version):
rake rails:freeze:edge TAG=rel_2-0-1
Note: It’s 2.0.1 because we found a small issue just after we pushed 2.0.0.
After another batch of fixes, tweaks, and buckets of polish, we’ve prepared the hopefully last step before 2.0 can go final: Release Candidate 2. If nothing major pops up, expect the final version to land within the next week or two at the most.
As usual, we got the latest gems on the gems.rubyonrails.org server and there’s a RC2 tag as well. Please put this final test through the ringer so we can get a clean 2.0.0 final release.
If you haven’t kept up to date on what’s new in 2.0, have a look at the original preview release announcement. The gem version for this release is 1.99.1. Enjoy!
After another batch of fixes, tweaks, and buckets of polish, we’ve prepared the hopefully last step before 2.0 can go final: Release Candidate 2. If nothing major pops up, expect the final version to land within the next week or two at the most.
As usual, we got the latest gems on the gems.rubyonrails.org server and there’s a RC2 tag as well. Please put this final test through the ringer so we can get a clean 2.0.0 final release.
If you haven’t kept up to date on what’s new in 2.0, have a look at the original preview release announcement. The gem version for this release is 1.99.1. Enjoy!
The rails core team has released ruby on rails 1.2.6 to address a bug in the fix for session fixation attacks (CVE-2007-5380). The CVE Identifier for this new issue is CVE-2007-6077.
You should upgrade to this new release if you do not take specific session-fixation counter measures in your application. 1.2.6 also fixes some regressions when working with has_many associations on unsaved ActiveRecord objects.
As with other 1.2.x releases, this is intended as a drop in upgrade for users of earlier versions in the 1.2 series.
To upgrade, `gem install rails`, set RAILS_GEM_VERSION to ‘1.2.6’ in config/environment.rb, and `rake rails:update:configs`.
The rails core team has released ruby on rails 1.2.6 to address a bug in the fix for session fixation attacks (CVE-2007-5380). The CVE Identifier for this new issue is CVE-2007-6077.
You should upgrade to this new release if you do not take specific session-fixation counter measures in your application. 1.2.6 also fixes some regressions when working with has_many associations on unsaved ActiveRecord objects.
As with other 1.2.x releases, this is intended as a drop in upgrade for users of earlier versions in the 1.2 series.
To upgrade, `gem install rails`, set RAILS_GEM_VERSION to ‘1.2.6’ in config/environment.rb, and `rake rails:update:configs`.
After a much larger delay than I would have liked, Capistrano 2.1 is now available! (Capistrano is a utility for executing commands on multiple remote machines in parallel, and is the tool of choice for many Rails developers for automating deployment.) There is a lot going on in this release, including some pretty exciting changes. As ever, install it via RubyGems with:
gem install capistrano
Here’s what’s new, roughly in order of magnitude:
No default PTY. Prior to 2.1, Capistrano would request a pseudo-tty for each command that it executed. This had the side-effect of causing the profile scripts for the user to not be loaded. Well, no more! As of 2.1, Capistrano no longer requests a pty on each command, which means your .profile (or .bashrc, or whatever) will be properly loaded on each command! Note, however, that some have reported on some systems, when a pty is not allocated, some commands will go into non-interactive mode automatically. If you’re not seeing commands prompt like they used to, like svn or passwd, you can return to the previous behavior by adding the following line to your capfile:
default_run_options[:pty] = true
Disable sh wrapping. Some shared hosts do not allow the POSIX shell to be used to execute arbitrary commands, which is what Capistrano has done since 2.0. If you’re on such a host, you can add the following line to your capfile:
default_run_options[:shell] = false
Capistrano will then run the command directly, rather than wrapping it in an “sh -c” command. Note, though, that this means that your own user shell on the remote hosts must be POSIX compatible, or you’ll get cryptic errors.
Git SCM support. Many thanks to Garry Dolley, Geoffrey Grosenbach, and Scott Chacon for their work on the new Git SCM module for Capistrano. If you’re a user of Git, you can now do:
set :scm, :git
Accurev SCM support. Thanks to Doug Barth, all you Accurev users can now enjoy Capistrano, too. Just do:
set :scm, :accurev
Rails’ Plugin Support. Capfile’s generated via the “capify” utility will now include a line that will autoload all recipes from vendor/plugins/*/recipes/*.rb. If you want this feature and you’ve already got a Capfile (and you don’t mind losing any changes you might have made to your Capfile), you can delete the Capfile and re-run “capify .”. Or, you can just add the following line to your Capfile, before the line that loads ‘config/deploy’:
Dir['vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }
Windows-safe reads. Any time Capistrano needs to read a file’s contents, it will now use the “b” flag, so that binary reads on Windows do not corrupt the file.
Cap shell and sudo. The Capistrano shell now properly recognizes sudo commands and prompts for the password correctly.
Use `match’ to check dependencies. There is a new remote dependency method for deploy:check: “match”. You can now look for arbitrary regular expressions in the output of various commands to see if things are set up correctly:
depend :remote, :match, "rake -V", /version 0\.7/
Namespaces#top. Sometimes you’ll find yourself wanting to execute a task from within another task, but the parent namespace of the target task is conflicting with a similarly-named namespace, and things are breaking. You can now use the “top” method to jump to the top of the namespace hierarchy:
namespace :apache do
namespace :deploy do
task :restart do
run "restart apache"
top.deploy.restart
end
end
end
Other changes. There are lots of other, smaller bug fixes and changes, too:
Enjoy! And please report any bugs on the Rails trac, with the component set to “Capistrano”.
New versions of the JavaScript libraries that ship with Rails, Prototype 1.6.0 and script.aculo.us 1.8.0, have been released. You can find out about the numerous changes on the Prototype blog and on mir.aculo.us. If you’re running Edge Rails, just svn up and run rake rails:update:javascripts to install the latest versions into your application automatically.
Also of note: Christophe Porteneuve’s Prototype & script.aculo.us book is now out of beta and available for purchase from the Pragmatic Programmers. It’s up-to-date with all of the new features in both libraries, so be sure to check it out if you’re using Prototype and script.aculo.us in your applications.
We’ve been taking our sweet time, but now it really is almost there. We’ve just pushed new beta gems to gems.rubyonrails.org and created the rel_2-0-0_RC1 tag. So this is shaping up to be the last chance to raise concerns for Rails 2.0 before we go final in oh-so-shortly.
So please give it a spin. First, upgrade to 1.2.5 if you haven’t already. Fix all the deprecation warnings you see. Then try to jump on Rails 2.0 and see if it runs. If it doesn’t, and you think it’s not because of something you did wrong, please create a ticket.
We’re going to be running this release candidate phase over the next couple of weeks, give or take depending on how many issues are raised.
You can read all about why you should actually care about Rails 2.0 in the original preview release announcement.
The gem version for this release is 1.99.0.
We’ve been taking our sweet time, but now it really is almost there. We’ve just pushed new beta gems to gems.rubyonrails.org and created the rel_2-0-0_RC1 tag. So this is shaping up to be the last chance to raise concerns for Rails 2.0 before we go final in oh-so-shortly.
So please give it a spin. First, upgrade to 1.2.5 if you haven’t already. Fix all the deprecation warnings you see. Then try to jump on Rails 2.0 and see if it runs. If it doesn’t, and you think it’s not because of something you did wrong, please create a ticket.
We’re going to be running this release candidate phase over the next couple of weeks, give or take depending on how many issues are raised.
You can read all about why you should actually care about Rails 2.0 in the original preview release announcement.
The gem version for this release is 1.99.0.
New versions of the JavaScript libraries that ship with Rails, Prototype 1.6.0 and script.aculo.us 1.8.0, have been released. You can find out about the numerous changes on the Prototype blog and on mir.aculo.us. If you’re running Edge Rails, just svn up and run rake rails:update:javascripts to install the latest versions into your application automatically.
Also of note: Christophe Porteneuve’s Prototype & script.aculo.us book is now out of beta and available for purchase from the Pragmatic Programmers. It’s up-to-date with all of the new features in both libraries, so be sure to check it out if you’re using Prototype and script.aculo.us in your applications.
After a much larger delay than I would have liked, Capistrano 2.1 is now available! (Capistrano is a utility for executing commands on multiple remote machines in parallel, and is the tool of choice for many Rails developers for automating deployment.) There is a lot going on in this release, including some pretty exciting changes. As ever, install it via RubyGems with:
gem install capistrano
Here’s what’s new, roughly in order of magnitude:
No default PTY. Prior to 2.1, Capistrano would request a pseudo-tty for each command that it executed. This had the side-effect of causing the profile scripts for the user to not be loaded. Well, no more! As of 2.1, Capistrano no longer requests a pty on each command, which means your .profile (or .bashrc, or whatever) will be properly loaded on each command! Note, however, that some have reported on some systems, when a pty is not allocated, some commands will go into non-interactive mode automatically. If you’re not seeing commands prompt like they used to, like svn or passwd, you can return to the previous behavior by adding the following line to your capfile:
default_run_options[:pty] = true
Disable sh wrapping. Some shared hosts do not allow the POSIX shell to be used to execute arbitrary commands, which is what Capistrano has done since 2.0. If you’re on such a host, you can add the following line to your capfile:
default_run_options[:shell] = false
Capistrano will then run the command directly, rather than wrapping it in an “sh -c” command. Note, though, that this means that your own user shell on the remote hosts must be POSIX compatible, or you’ll get cryptic errors.
Git SCM support. Many thanks to Garry Dolley, Geoffrey Grosenbach, and Scott Chacon for their work on the new Git SCM module for Capistrano. If you’re a user of Git, you can now do:
set :scm, :git
Accurev SCM support. Thanks to Doug Barth, all you Accurev users can now enjoy Capistrano, too. Just do:
set :scm, :accurev
Rails’ Plugin Support. Capfile’s generated via the “capify” utility will now include a line that will autoload all recipes from vendor/plugins/*/recipes/*.rb. If you want this feature and you’ve already got a Capfile (and you don’t mind losing any changes you might have made to your Capfile), you can delete the Capfile and re-run “capify .”. Or, you can just add the following line to your Capfile, before the line that loads ‘config/deploy’:
Dir['vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }
Windows-safe reads. Any time Capistrano needs to read a file’s contents, it will now use the “b” flag, so that binary reads on Windows do not corrupt the file.
Cap shell and sudo. The Capistrano shell now properly recognizes sudo commands and prompts for the password correctly.
Use `match’ to check dependencies. There is a new remote dependency method for deploy:check: “match”. You can now look for arbitrary regular expressions in the output of various commands to see if things are set up correctly:
depend :remote, :match, "rake -V", /version 0\.7/
Namespaces#top. Sometimes you’ll find yourself wanting to execute a task from within another task, but the parent namespace of the target task is conflicting with a similarly-named namespace, and things are breaking. You can now use the “top” method to jump to the top of the namespace hierarchy:
namespace :apache do
namespace :deploy do
task :restart do
run "restart apache"
top.deploy.restart
end
end
end
Other changes. There are lots of other, smaller bug fixes and changes, too:
Enjoy! And please report any bugs on the Rails trac, with the component set to “Capistrano”.