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! ☃
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.
Includes more prep-work for Rails 3, conventions for the use of flash (the store), XSS prevention, and more.
I do have a problem running my RSpec 1.3.0 suite in my app at the moment and haven’t really found out what’s causing it. Expectations on ActiveRecord classes cause the specs to blow up. Hopefully this is cleared shortly.
Still ships with a couple of known regressions, but claimed to be the last beta before a release candidate.
Big One-Oh release of the most awesome Solr full-text search plugin for Ruby and Ruby on Rails. This release focusses on the current 1.4 generation of Solr released last November.
Major new features include extensions to the already splendid faceting support such as multiselect facets and named field facets, new field types, session proxies, support for class reloading, and deletion by query.
Upgrading from a pre-1.0 release is easy, just follow the instructions in the linked blog post.
$12 eBook with step-by-step upgrade information for your Rails 2.x apps.
To install:
gem install tzinfo builder memcache-client rack rack-test rack-mount erubis mail text-format thor bundler i18n
gem install rails --pre
Be sure to click through for a rundown of headliner features and also check Jeremy McAnally’s various excellent posts for upgrading existing applications and starting a new application.