This Week in Edge Rails

November 29-December 5, 2008 Edition

Rails 2.3 development is still continuing at a healthy clip. Here’s an overview of what’s happened this week.

Application Templates

Rails now incorporates Jeremy McAnally’s rg application generator. What this means is that we now have template-based application generation built right into Rails; if you have a set of plugins you include in every application (among many other use cases), you can just set up a template once and use it over and over again when you run the rails command. Pratik Naik provided a thorough writeup of this feature over on his blog. commit

Find Improvements

Even the venerable code used by Active Record to talk to databases can be improved, and we had a couple of improvements checked in this week. First, the SQL generated for preloading records in has_and_belongs_to_many associations has had an extra “AS” excised, which makes it work better with some databases. Also, we now have a :having option on find (as well as on has_many and has_and_belongs_to_many associations) for filtering records in grouped finds. As those with heavy SQL backgrounds know, this allows filtering based on grouped results:


developers =  Developer.find(:all, :group => "salary", 
  :having => "sum(salary) >  10000", :select => "salary")

commit commit

Rack Integration

The tighter integration of Rails with Rack continues. This week saw the death of the venerable CGI processor within Rails, as well as the use of Rack to handle FCGI. There was also some refactoring down in the Rails tests to make them play nicer with Rack. commit commit

Configuration File Cleanup

Over the years, the default environment.rb file had gotten a bit cluttered with comments, random documentation, and settings that mot people don’t need. DHH took a few minutes to clean up the mess, and the current state of this file is much leaner. As part of the cleanup, session store configuration has been moved out to its own file. commit

No More Process Scripts

If you’re one of the (fairly rare) Rails developers who deploys in a fashion that depends on the inspector, reaper, and spawner scripts, you’ll need to know that those scripts are no longer included in core Rails. For Rails applications that are reployed with current alternatives like Passenger, these are just unnecessary baggage. But if you need them, you’ll be able to pick up copies via the irs_process_scripts plugin. commit

Odds and Ends

The fact that Rails checks for IP spoofing can be a nuisance for sites that do heavy traffic with cell phones, because their proxies don’t generally set things up right. If that’s you, you can now set ActionController::Base.ip_spoofing_check = false to disable the check entirely. commit

Rails.root now returns a Pathname object, which means you can use it directly with the join method to clean up existing code that uses File.join. commit

ActionController::Dispatcher now implements its own middleware stack, which you can see by running rake middleware. commit

Gem loading is smarter about missing dependencies. commit

auto_link now properly applies options (such as :target and :class) to generated e-mail links. commit

Phusion Passenger 2.0.5 now compatible with Edge Rails

The Phusion team keeps blazing ahead with Passenger and improving it rapidly. They’ve just released version 2.0.5, which includes a few fixes and introduces compatibility with the Rack-based Edge Rails.

At 37signals, we’ve already switched over Ta-da List and are busy working on getting the rest of our suite running on Passenger. It’s just so much easier to deal with and the memory savings you get through REE are a nice cherry on top.

I keep getting a steady stream of success reports from all over the world as well. I’ve even read of a few people getting back into Rails development because Passenger finally took out the inconvenience of deploying.

It’s hard to argue with the usability. I’ve personally been setting up a new server running Ubuntu 8.10 and using Apache 2 with Passenger. The time it took me to go from a fresh install to a complete production setup was ridiculously low. There’s just so much less to worry about.

If you haven’t given Passenger a chance yet, now is definitely the time.

This Week in Edge Rails

Yesterday was Thanksgiving holiday for US-based developers – but it certainly hasn’t looked like a holiday week in edge Rails. Things are moving fast, with some major changes afoot for version 2.3 of Rails.

Rack integration

The underpinnings of script/server have been simplified and rewritten somewhat. The explicit list of supported servers that used to be in script/server is gone. Instead, Rails now depends on the installation of Rack, and script/server goes through this – which means that Rails supports any server that Rack does.

Efficient routes

Routing sees a couple of big changes this week. The formatted_ route helpers are gone, in favor just passing in :format as an option. This cuts down the route generation process by 50% for any resource – and can save a substantial amount of memory (up to 100MB on large applications, according to the Lighthouse ticket ) If your code uses the formatted_ helpers, it will still work for the time being – but that behavior is deprecated and your application will be more efficient if you rewrite those routes using the new standard. Another big change is that Rails now supports multiple routing files, not just routes.rb. You can use RouteSet#add_configuration_file to bring in more routes at any time – without clearing the currently-loaded routes. commit commit

Better support for engine plugins

The second routing change enables better support for Rails Engines: routing files in engines are automatically loaded and reloaded now (as are those in other plugins). Engines are getting some love other than routing. If your plugin has an app folder, then app/[models|controllers|helpers] will automatically be added to the Rails load path. There’s active discussion of just how this should work, and how much to pick up from the current engines plugins, so it’s likely we haven’t seen the last commits in this area. Engines also support adding view paths now. commit commit commit commit

Sensible backtraces for your tests

If you’re a fan of the Thoughtbot Quiet Backtrace plugin, which allows you to selectively remove lines from Test::Unit backtraces, you’ll be happy to find ActiveSupport::BacktraceCleaner and Rails::BacktraceCleaner in core. This supports both filters (to perform regex-based substitutions on backtrace lines) and silencers (to remove backtrace lines entirely). Rails automatically adds silencers to get rid of the most common noise in a new application, and builds a config/backtrace_silencers.rb file to hold your own additions. commit

Ruby 1.9 integration

A variety of commits continue the drive towards Ruby 1.9 and minitest compatibility. This should ensure that Rails 2.3 is ready to handle the latest Ruby underpinnings when it’s released. Those on the bleeding edge at the moment need to beware, though: one of the changes in edge Rails depends on a ruby-core patch that hasn’t yet been applied there. You’ll also (temporarily) need to pick up Jeremy Kemper’s fork of Mocha for MiniTest compatability as required by this commit .

Faster boot time in development mode with lazy loading/autoload

Jeremy Kemper and Josh Peek have been doing a ton of work on making sure that bits of Rails (and its dependencies) are only brought into memory when they’re actually needed. Check out the commits from November 23 for a bunch of lazy-loading changes. The core frameworks – Active Support, Active Record, Action Controller, Action Mailer and Action View – are now using autoload to lazy-load their individual classes. This work should help keep the memory footprint down and improve overall Rails performance. commit commit commit commit commit

Misc

You can specify using the new preload_frameworks option whether the core libraries should be autoloaded at startup. This defaults to false so that Rails autoloads itself piece-by-piece, but there are some circumstances where you still need to bring in everything at once – Passenger and JRuby both want to see all of Rails loaded together. commit

Asset hosts get more flexible in edge Rails with the ability to declare an asset host as a specific object that responds to a call. DHH has supplied a sample project, asset-hosting-with-minimum-ssl , that demonstrates one good use for this functionality. commit

You can now configure the location of the helpers folder for a Rails application by setting ActionController::Base.helpers_dir. This will be a boon in some unusual circumstances – the original use case is for building a Rails application that encourages extension via plugin rather than by altering the application itself. commit

Token generation for CSRF protection has been simplified; now Rails uses a simple random string generated by ActiveSupport::SecureRandom rather than mucking around with session IDs. As a result, the :digest and :secret options to protect_from_forgery are deprecated and have no effect on edge. commit

While we’re on the subject of secrets, some people will find novel uses for ActiveSupport::MessageEncryptor, which provides a simple way to encrypt information for storage in an untrusted location (like cookies). commit

Active Support’s from_xml no longer depends on XmlSimple. Instead, Rails now includes its own XmlMini implementation, with just the functionality that it requires. This lets Rails dispense with the bundled copy of XmlSimple that it’s been carting around. commit commit

As you probably recall, last week’s improvements included the renaming of application.rb to application_controller.rb. This week there’s a new rake task, rake rails:update:application_controller to do this automatically for you – and it will be run as part of the normal rake rails:update process. commit

Good news if you’re using ActiveSupport::OrderedHash: it now implements each_key and each_value. commit

One more bit of core Rails is open to I18n: the units used by number_to_human_size. If you’re maintaining a translation file, you need to add the storage_units: [Bytes, KB, MB, GB, TB] to your translations. commit

Support for Rails components – which were famously called “a shining example of what happens when eagerness overtakes prudence” in Agile Web Development With Rails – is finally gone. If a couple of years of warning about this deprecation wasn’t enough for you, then it’s time to find an alternate solution at last. commit

Various files in /public that deal with CGI and FCGI dispatching are no longer generated in every Rails application by default (you can still get them if you need them by adding --with-dispatches when you run the rails command, or add them later with rake rails:generate_dispatchers). commit commit

Just a reminder: I’m not providing pointers to every single commit here, just trying to highlight things. This week’s edge changes actually included 136 commits from a wide variety of contributors.

New 15-minute blog video on Rails 2.2

The old 15-minute blog video was getting really long in the tooth, so it’s with great pleasure that I can present the new video made with Rails 2.2 and done by Ryan Bates. It really takes it all up a notch by showing the creation of a blog with comments, ajax, feed, api, admin interface, and more.

Ryan Bates is also the author of the wonderful Railscasts.com site that features video explanations on Rails features. It’s a fantastic resource and now properly recognized on the screencasting page.

I’ve also linked up the commercial Rails screencasters. The amount of material available for people interested in learning by video is simply staggering.

Rails 2.2: i18n, HTTP validators, thread safety, JRuby/1.9 compatibility, docs

Rails 2.2 is finally done after we cleared the last issues from the release candidate program. This release contains an long list of fixes, improvements, and additions that’ll make everything Rails smoother and better, but we also have a number of star player features to parade this time.

Internationalization by default
The most important is that Rails now includes a full-on internationalization framework and that it’s pre-wired from start. The work of the i18n group has been very impressive and it’s great to see that Rails finally ships with a solution in the box that’s both simple and extensible. Great job, guys!

Stronger etag and last-modified support
We’ve also added much better support for HTTP validators in the form of etag and last-modified. Making it so much easier to skip expensive procesesing if the client already has the latest stuff. This also makes it even easier to use Rails with gateway proxies.

Thread safety and a connection pool
Josh Peek has added thread safety to Rails and Nick Sieger from JRuby worked on getting Active Record a proper connection pool. So now all elements of Rails are thread safe, which is a big boon for the JRuby guys in particular. For C Ruby, we still need a bunch of dependent libraries to go non-blocking before it’ll make much of a difference, but work on that is forth coming.

Ruby 1.9 and JRuby compatibility
Jeremy Kemper has been rocking on both Ruby 1.9 and JRuby compatibility. Rails 2.2 is fully compatible with both, but again, there might be supporting libraries and gems that are not. Again, lots of work is going into making everything else fully compatible as well.

Better API docs, great guides
Finally, the last big push has been with the documentation of Rails. Pratik’s docrails project has made immense progress. Not only are the API docs much improved, but we also have a whole new guides section generated from documentation that now lives with the source. A true community project with lots of contributors. I’m sure both those new and old to Rails will greatly appreciate the strong focus on documentation.

To read about all these features and more in details, checkout the Rails 2.2 release notes — another one of those guides from the docrails project.

How to install
As always, you can install Rails 2.2 through RubyGems. We now require RubyGems 1.3.1, so be sure to update that first: gem update --system

Then you can install Rails: gem install rails

If you’re updating an existing application, you can run rake rails:update to get the latest JavaScript files and scripts.

From all of us to all of you, we hope you enjoy this release. It’s a true pleasure to see Rails make such big steps forward once again. Dig in, have fun, and we’ll be back with Rails 2.3 with even more before you know it.

This Week in Edge Rails

First up this week, a warning for those who don’t closely follow the state of the Rails repository – “edge” really means edge now. The bits for 2.2 are getting locked down for release, and the repository has been forked; for the moment, edge Rails is being identified as 2.3 , though that projected version number might change later. If you’re trying to install almost-released 2.2 bits on your machine, make sure you’re using the 2-2-stable branch, and not edge, which is currently seeing some major changes.

The 2-2-stable code is still seeing changes, but they’re either bug fixes or very small things. This week, that includes fixing a bug in assignment to has_one :through associations , some further tuning of CSRF protection , a fix to handling of checkboxes for Boolean attributes , updating the bundled copies of TZInfo, Prototype, and script.aculo.us, and some Ruby 1.9 compatibility work (though currently full Ruby 1.9 compatibility is targeted for Rails 2.3).

The biggest feature change in the 2.2 branch is the addition of explicit I18n support to newly-generated Rails projects, including a sample locale file, auto-loading all locales in config/locales, and sample settings in config/environment.rb. commit

Also worth noting in 2.2 is a chunk of code removal: a whole mess of special case tests for the SQL Server adapter have been chopped out of the Active Record test cases. That’s because Ken Collins has done tremendous work in making the SQL Server adapter work the way that Rails expects data adapters to work, giving us a big step in the area of backend portability. commit

On the actual edge code (the master branch in the repository), there’s a lot more action. With that branch just opened, some pent-up code has been checked in, and some big changes are being made. It’s an exciting time, and edge is definitely worth checking out. Here are some of the most notable changes in the past week.

One big set of changes has come from Jeremy Kemper, who has been overhauling the internal Rails testing to switch from Test::Unit::TestCase to ActiveSupport::TestCase. This work also includes requiring Mocha to test Rails (in the 2.2 code, some tests are skipped if you don’t have Mocha installed) and generally making the Rails testing strategy (both within core and for generated applications) more consistent moving forward.

If you’re one of the people who has always been bothered by the special-case naming of application.rb, rejoice! It’s been reworked to be application_controller.rb in the edge code. More info here and here . commit

Rails 2.3 will introduce the notion of default scopes : similar to named scopes, but applying to all named scopes or find methods within the class. For example, you can write default_scope :order => 'name ASC' and any time you retrieve records from that class they’ll come out sorted by name (unless you override the option, of course). commit

A lot of folks have adopted the notion of using try() to attempt operations on objects – Here’s Chris Wanstrath’s blog post introducing it. It’s especially helpful in views where you can avoid nil-checking by writing code like <%= @person.try(:name) %>. Well, now it’s baked right into Rails. commit

Also new on the syntactic sugar front is Enumerable#none? to check that none of the elements match the supplied block. commit

The render method has been getting smarter over the years, and it’s going to be even smarter in 2.3. If you have an object or a collection and the naming matches up, you can now just do <% render @article %> or <% render @articles %> and things will just work. Ryan Daigle has some more examples on this. commit

On a somewhat similar note, render_component goes from “deprecated” to “nonexistent” in 2.3. If you still need it, you can install the plugin . commit

The autolink helper has been refactored to make it a bit less messy and more intuitive. commit commit

There’s a fix to a memory leak connected to thread safety and asset tags, that could bite sites that were referencing a lot of external images. Aaron Batalion contributed the fix, as well as a blog post explaining the issue. commit and commit

Finally, it’s worth mentioning that some controversy has erupted over a change made to the 2.2 code five months ago – the addition of Array#second through Array#tenth as aliases for Array#[1] through Array#[9]. Without taking a stand on the controversy (I’ve done that elsewhere), I’ll just note that the most recent edge checkin as I write this trims this down to only support Array#second through Array#fifth – and uses the savings in overhead to implement Array#forty-two. commit

Potential Circumvention of CSRF Protection in Rails 2.1

There is a bug in all 2.1.x versions of Ruby on Rails which affects the effectiveness of the CSRF protection given by protect_from_forgery.

By design rails does not perform token verification on requests with certain content types not typically generated by browsers. Unfortunately this list also included ‘text/plain’ which can be generated by browsers.

Impact

Requests can be crafted which will circumvent the CSRF protection entirely. Rails does not parse the parameters provided with these requests, but that may not be enough to protect your application.

Affected Versions

  • All releases in the 2.1 series
  • All 2.2 Pre Releases

Fixes

The upcoming 2.1.3 and 2.2.2 releases will contain a fix for this issue.

Interim Workarounds

Users of 2.1.x releases are advised to insert the following code into a file in config/initializers/

> Mime::Type.unverifiable_types.delete(:text)

Users of Edge Rails after 2.2.1, should upgrade to the latest code in 2-2-stable.

The patch for the 2.1.x series is available on github. This will also apply cleanly to 2.2 pre-releases prior to this changeset released on Thursday November 13th at 11:19:53 2008 CET. Users with edge-rails checkouts after that date, are advised to upgrade to the latest code in 2-2-stable.

Thanks to Steve from Coderrr for reporting this issue.

New Rails 2.2 i18n defaults

I just reduced the housework needed to setup a new Rails application with i18n. All new applications will ship with a config/locales directory that’s automatically wired up in the load path for i18n. So you can just drop .yml or .rb locale files in there and they’ll be instantly available for translation.

There’s also a sample config/locales/en.yml file in there to give you a starting point. In addition, the initializer is now wired up through the Rails config. The new default environment.rb provides these pointers:

# The internationalization framework can be changed 
# to have another default locale (standard is :en) or more load paths.
# All files from config/locales/*.rb,yml are added automatically.
# config.i18n.load_path << Dir[File.join(RAILS_ROOT, 'my', 'locales', '*.{rb,yml}')]
# config.i18n.default_locale = :de

So on a fresh Rails 2.2 application, you’ll be able to do see it all wired up out of the box (the :hello key is from the config/locales/en.yml demo file):

$ ./script/console
>> I18n.t :hello
=> "Hello world"

Rails 2.2 final is just around the corner. We’ve been ironing out the last bugs and added the last amount of polish to make this a kick ass release. Also, work on 2.3 / 3.0 has already begun in master as well since we’ve branched for 2.2 a while back.

Rails 2.2 RC2: Last stop before final

Rails 2.2 has been baking for long enough now. This is the last taste before the goodies are served. So please install and check it out. See if you can find any regressions or bugs in any of the new stuff, so we can have it all delicious by the time we ring the dinner bell (ok, ok, I’ll put down the food metaphor now).

This release also conciedes with the fact that we’ve branches 2-2-stable, which means that master is now actually targeting Rails 2.3/3.0. There’s also a tag available for this RC as v2.2.1.

If you missed RC1, have a look at the Rails 2.2 release notes to see the major additions. You can see what’s new since RC1 in these two This Week in Edge Rails.

To install, you must first have RubyGems 1.3.1:
gem update --system.

Then you can:
gem install rails -s http://gems.rubyonrails.org

Enjoy!

This Week in Edge Rails

The important news in edge Rails this week is the imminent release of Rails 2.2.1 – otherwise known as Rails 2.2 RC2. Getting ready for this release did lead to some significant changes in the Rails codebase.

First, it’s very likely that you’ll need to upgrade rubygems to run RC2: the required version of rubygems is now 1.3.1, which was just released yesterday. This dependency is part of the continued work to make vendored gems useful and stable. You may find that updating rubygems is less than smooth, depending on your current version; check out this article if you have any trouble. commit

The Rails routing engine has seen some serious work over the past week as well. For starters, Jeremy Kemper committed several fixes to the core routing engine that cut down on object creation and RegExp creation, trimming memory use. commit commit There are also new :only and :except options for map.resources, which can help cut down memory use if you have a lot of resource routes – see these articles for details (though there have been some tweaks in the way nested limited routes work after those were written). commit commit commit

The new ActiveRecord connection pooling code has seen some tuning as well, making it more efficient in development model and avoiding some issues with the Oracle adapter. commit

Polymorphic URLs now behave more intuitively if one of their parameters is nil. For example, a call to polymorphic_path([project, filter, @issue]) with a nil filter now returns project_issue_url instead of a NoMethodError. commit

The request forgery protection feature in Rails has been tightened up so that it only applies to HTML-formatted content requests. There is substantial discussion on the Lighthouse ticket that led to this change, but the bottom line is that the old implementation had some bugs, notably making destroy actions inaccessible via XML. Other types of requests are protected by other means – for instance, the same origin policy on AJAX requests substitutes for request forgery protection there. commit