December 10th, 2007
I know I said I was going to try and keep the features in “a feature a day” to those not mentioned in popular places, but this feature is one of the few nicest features in Rails made by a contributor outside of the Rails core so I couldn’t resist mentioning it.
First, an example
class CommentsController < ActionController::Base
rescue_from Comment::Spammy, :with => :moderate_comment
rescue_from ActiveRecord::RecordNotFound, :with => :redirect_if_not_found
protected
def moderate_comment
# Handle the exception, like placing the comment in a moderation queue
# and then rendering a different action.
end
def redirect_if_not_found
# Redirect somewhere...
end
end
Compare this to what you had to do with Rails 1.2.6 and earlier:
class CommentsController < ActionController::Base
def rescue_action_in_public(exception)
case exception
when Comment::Spammy
# Handle the exception as above.
when ActiveRecord::RecordNotFound
# Redirect somewhere...
else
super
end
end
end
Much clearer and reads almost like English. I don’t think I even need to explain what the code in the 1st example is trying to do.
Let’s try another example
Here’s another common use-case: dealing bad create/update actions. With rescue_from, you can simply do this:
class ApplicationController < ActionController::Base
rescue_from ActiveRecord::RecordInvalid do |exception|
render :action => (exception.record.new_record? ? :new : :edit)
end
end
No need for actions to be coded like this anymore!
def create
@comment = comment.create!(params[:comment])
rescue ActiveRecord::RecordInvalid
render :action => :new
end
This patch was committed in revision 7597 after a short discussion on the syntax and implementation over at the ticket. (More improvements on the implementation over at ticket #9645 for the interested.)
About the contributor, Norbert Crombach
Norbert Crombach (Rails Trac username: norbert, WorkingWithRails profile) is another regular Rails contributor hailing from the Netherlands. The rescue_from is, in my opinion, one of his more significant contributions (and what a great one it is too).
Some final words
While the new declarative rescue_from macro is useful, I’ve found myself liking the merb way of dealing with exceptions, where exception handling is delegated to an Exception controller. You can use layouts, templates, helpers and filters just like in ye plain olde controller. I’m still not so sure if it’s worth making a patch for Rails to emulate this behavior yet though!
Update: Rails 2.0 a feature a day #3 is now available Concatenate your stylesheets and JavaScripts in 3 seconds
December 9th, 2007
Time#advance and DateTime#advance just got, erm, more betterer in Rails 2.0.
In Rails 1.2.6 and earlier, Time#advance and DateTime#advance only accepted :year, :month and :day options. You’d think :hours, :minutes and :seconds would work too but due to a bug in the code (see ticket #9818), you get something like this instead:
time = Time.utc(2000,10,1,10,30,45)
# => Sun Oct 01 10:30:45 UTC 2000
time.advance(:days =>3, :hour => 2)
# => Wed Oct 04 02:00:00 UTC 2000
Notice how the hour is changed instead of being advanced.
Now, thanks to Geoff Buesing’s efforts, passing :hours, :minutes and :seconds options work as you’d expect:
time = Time.local(2005,2,28,15,15,10)
# => Mon Feb 28 15:15:10 0800 2005
time.advance(:hours => 5, :minutes => 20, :seconds => 25)
# => Mon Feb 28 20:35:35 0800 2005
Hell, you can even #advance by :weeks (see ticket #9866):
time = Time.local(2005,2,28,15,15,10)
# => Mon Feb 28 15:15:10 0800 2005
time.advance(:weeks => 2)
# => Mon Mar 14 15:15:10 0800 2005
+1 for consistency and properly behaving code. Thanks to this #advance patch, Geoff was also able to re-use #advance to refactor some other parts of ActiveSupport’s time-related extensions.
About the contributor, Geoff Buesing
Geoff Buesing is a regular Rails contributor and I’ve known him to be the date/datetime/time guru - just look at his submitted patches if you’re not convinced. Not too long ago Geoff was given well-deserved commit rights (congrats Geoff)! You won’t find him on the Ruby on Rails Core team page yet though - it’s probably out of date.
Check out his blog at mad.ly where he writes mostly his adventures with on unobtrusive JavaScript in Rails.
December 9th, 2007
Now that Rails 2.0 has been baked to near-perfection, I’m sure all you Rubyists with Rails applications are considering updating or have already updated your applications to be Rails 2.0-compatible. And you’ve probably already pored through the massive list of new features and changes in Rails 2.0 or seen it on Ryan Daigle’s Scraps. Ryan also wrote a Rails2 mini eBook that’s been getting good reviews.
I’ve been keeping track of the Rails Trac timeline myself since my 1st committed Rails patch mostly to keep track of Rails development (we run several apps on edge) and to monitor any comments on my submitted patches. Turns out keeping an eye on the timeline and the rubyonrails-core mailing list gives you a pretty decent “on the ground” view of new features and changes to the Rails trunk.
So I’m gonna try something and see if helps anyone: I’ll be running a near-daily series of blog posts about new Rails features or changes. I’ll try not to repeat anything that’s already been mentioned, and instead focus more on lesser-known changes. I think it’s also a great opportunity to raise the profile of the core committers and contributors to the Rails community so look out for an “About the contributor” section in each post.
Hop on over to the 1st post - Time#advance now uses :weeks, :hours, :minutes, :seconds options.
December 8th, 2007
Just go to the release announcement and major features blog post by DHH already!
If you’re having trouble installing the Rails 2.0.1 gem, do a gem install rails -y --source http://gems.rubyonrails.org
Now that the obligatory link to the Rails 2.0 release announcement is done, I’d like to urge anyone with any interest in improving Rails or seeing new features or fixes in Rails to try and contribute to Rails. I’m sure everyone of us Rails users have had “what if Rails could do this” or “why is Rails doing this, that’s just wrong” moments. Well, roll up your sleeves and help by contributing instead of complaining about how “they” won’t/haven’t/are too stupid to fix it..
A good starting point is to read the Rails Trac wiki, and after that be sure to check out John Susser’s excellent guide to contributing to Rails (read the presentation slides, it won’t take long). You should have enough information to start. I recommend just opening the base.rb classes for ActiveRecord, ActionController and peeking around the ActiveSupport classes just to get a feel of things. After that crack open the relevant test for your issue and write your test-driven patch!
It’s really easy, since Rails is written purely in Ruby - if I can do it I’m sure you can too :) Your contribution doesn’t even have to be a bona fide patch file with tests, documentation and bits of Ruby code - if you notice a bug and report it not knowing how to fix it, that’s good enough! Or even something as trivial as a new style (CSS and layout) for the Rails error pages (there isn’t such a patch yet but I’d love to see prettier default exception pages instead of the current rather plain-looking ones).
Anyway, that’s enough of the sermon from me - enjoy your Rails 2.0! Congrats to the Rails Core team and contributors on another solid release!
December 7th, 2007
Update: Looks like it’s going to be released as Rails 2.0.1 instead due to a bugfix post-2.0 tagging.
Just a quick one - seems like Rails 2.0 has been tagged for release. Rails 2.0 milestone has just been completed.
Expect a post on weblog.rubyonrails.com soon.