The release candidate of Rails 3 released yesterday contains quite a few surprises for the careless updater from earlier Rails 3 betas (me totally included). As usual, a proper test suite will save your bacon.
Here is the list of pitfalls I encountered, with an advised solution/workaround where available.
Before you start getting weird errors, do yourself a favor and manually install the Bundler gem or the Rails gem (instead of going through Bundler itself trying to resolve this meta-version-inter-dependency-hell).
$ gem install bundler --pre
or install the Rails pre-release manually, since it depends on the Bundler pre-release
$ gem install rails --pre
This will bite you on your staging/production servers at the very latest. Bundler 1.0.0.rc will also completely make over with your existing Gemfile.lock, so don’t be surprised to find a completely new (and excitingly readable) format after you bundle install.
On a related note, bundle install --relock is gone. I am under the impression that bundle install (without arguments) will now just default to relocking the bundle if a Gemfile.lock is detected.
Between Beta 4 and the Release Candidate, the Core Team actually snuck in a few extra deprecation warnings that will affect those coming from earlier betas. Newly generated applications (by way of rails new <appname>) will be generated with the new syntax.
First of all, you will get “Calling a method in Rails::Application is deprecated” for any and all rake tasks. The fix goes into your Rakefile and is very simple. (Please substitute YourAppName for the actual name of your application.)
# Old
Rails::Application.load_tasks
# New
YourAppName::Application.load_tasks
Additionally, running your tests may reveal another deprecation notice to the effect of “You are using the old router DSL which will be removed in Rails 3.1”, with an unhelpful pointer to deprecated_wrapper.rb. This time, the fix goes into your config/routes.rb:
# Old
YourAppName::Application.routes.draw do |map|
# ..
end
# New
YourAppName::Application.routes.draw do
# ..
end
Spot the difference? And the notice is gone.
Additionally, there’s an environment-specific way to declare your desire to receive deprecation warnings (or not). These are the recommended settings:
# config/environments/test.rb
config.active_support.deprecation = :stderr
# config/environments/development.rb
config.active_support.deprecation = :log
Ironically enough, even that will make another warning go away.
If you rely on libraries in your application’s lib/ sub-directory being auto-loaded when you start using their class names in your code, you need to add a passage to your application’s configuration:
# config/application.rb
module YourAppName
class Application
config.autoload_paths += %W(#{config.root}/lib)
# ..
end
end
In a cruft cleaning attempt, ActiveRecord::Base#class_name has been removed. You can use Update: Jeremy McAnally suggested using ActiveRecord::Base#to_s as a likely replacement. (Worked in my simple use cases.)ActiveRecord::Base#model_name as the replacement. Thanks!
While we’re waiting for the official rails-i18n repository to update most of their language files (or fork away and fix it yourself), please be aware that you will see even more deprecation warnings regarding the interpolation of variables within the translation strings.
# Old
other: 'etwa {{count}} Stunden'
# New
other: 'etwa %{count} Stunden'
So it’s just like regular Ruby string interpolation.
Object#returning has been present in ActiveSupport for quite a while and supported concise constructs where you’re manipulating an object multiple times before finally returning it from the method. Well, Object#returning is dead, long live Object#tap, which has a slightly different syntax.
# Old
returning([]) do |output|
# ..
end.join("\n")
# New
[].tap do |output|
# ..
end
Basically, it’s a little cleaner and potentially less confusing with a regular return statement.
Last, but by no means least, the underlying implementation of ActiveRecord::Base#update_attribute was changed drastically. On the surface, it’s for the better. But upgrading applications that depend on the old behavior is going to be a major headache and source for very subtle bugs.
It will only save the attribute it has been asked to save and not all dirty attributes
If you’d been using update_attribute as a sort of “final call” to changing a potentially protected attribute and then making that save the whole record (with additional dirty fields), this will now only update the field passed to update_attribute itself and will not go through a regular save operation. The underlying implementation actually makes a direct SQL call to accomplish this.
It does not invoke callbacks
This will get you if you relied on the fact that callbacks indeed fired with the use of update_attribute. One example would be the usage of the excellent friendly_id plugin that takes care of auto-generating permalink slugs for your models and also has a way to keep those slugs in sync with the fields they’re derived from. If, for some reason, you were to use update_attribute on said field, the callback to update the slug will not fire and thus the permalink will be out-of-date.
Keep your eyes open and let me know if you run into other issues or gotchas worth publishing.
PS: Snowman! ☃
I attended Joe McNally’s lighting workshop at the Business Design Centre in Islington, London on July 23rd. While it wasn’t a hands-on workshop, due to the sheer fact that more than 500 people attended it, but Joe is such an outstanding photographer and trainer that it was still totally worth the journey from Germany.

All in all, it was a whirlwind tour for on-location and studio lighting using mainly small flashes and a variety of light modifiers to achieve the desired looks. The stage setup was simply a white seamless (with an, admittedly, incredibly high ceiling).

They brought along two professional models, Anna and Ollie, which were both great and professional and a joy to photograph (I assume.) Anna was especially versatile with her two outfits (more on that below).

Joe never really got a break since people ran up to the stage in a stampede to have him authograph copies of his books or just discuss all things photography. He barely got out for the hour of lunch-break that was scheduled since people kept on approaching him. He dealt with all that really patiently and professionally, which he gets my highest respect for.

While Joe shot 90% of all the setups with small flashes (a battery of 4-8 SB-900 flashes on the set all of the time, triggered with an SU-800 or SB-900 on camera using TTL), later on he broke out the bigger lights. In this case, these were Elinchrom Quadra units in a clam shell setup.

He also used his proven tethering setup, connecting his Nikon D3s to his MacBook Pro using Nikon’s Camera Control Pro software. The MacBook was then connected to two projectors, so the entire audience could actually see the results of Joe’s shooting.
More behind-the-scenes shots are available in my Flickr Stream.
In summary, it was an intense day spent with one of the most incredible photographers on the face of the earth right now, with a lot of great spirit and entertainment. I’m really looking forward to putting some of the tricks I learned to good use in the months and years to come.
jQuery Visualize: Accessible Charts with HTML5 -
The Visualize plugin parses key content elements in a well-structured HTML table, and leverages that native HTML5 canvas drawing ability to transform them into a chart or graph visualization. For example, table row data values serve as chart bars, lines or pie wedges; table headers become value and legend labels; and the title and caption values provide title labels within the image.
Along with my iPhone 4 (ordered from the UK Apple Store) I received another brilliant accessory for another Apple device in a consolidated shipment from Borderlinx: The Qubits iPad Stand, which I ordered from Amazon UK after a recommendation by @mattgemmell a while back.
This thing is truly amazing; it’s sturdy (can’t kick the iPad off easily), quite flexible in the angle of adjustment (works for plain viewing and also at low angles for lots of typing), works with cases (like the excellent Marware Eco-Vue) and with the sync cable connected, and at £19 it’s also pretty affordable.

Here’s the original video from @mattgemmell that made me buy it in the first place.
Hot on the heels of MoviePeg for iPhone comes MoviePeg for iPad, now available for pre-order.
Sitting straight 'bad for backs' -
BBC News:
In this study, the patients assumed three different sitting positions: a slouching position, in which the body is hunched forward as if they were leaning over a desk or a video game console, an upright 90-degree sitting position; and a “relaxed” position where they leaned back at 135 degrees while their feet remained on the floor.
I’ve been suffering from worn discs (on the lowest two levels) on and off for more than 10 years now. Most of the time I’m doing okay, other times it’s more pronounced and I can hardly move. Looks like I should’ve used the leaned back position on the Aeron much more often.
Hongli Lai:
Phusion Passenger Lite consists of an Nginx core. Nginx is known to be extremely scalable, high-performance and lightweight. You do not need to have Nginx already installed; this is automatically taken care of. You also do not need to have any Nginx experience: Nginx is hidden from the user but its power is automatically utilized.
With previous iPhones, it was like dropping a piece of buttered toast — there was a lucky and unlucky side on which it could land. With the iPhone 4, it’s like dropping a piece of toast that’s been buttered on both sides. — Daring Fireball: 4