May 11th, 2008
This week’s report covers changes from 5th May 2008 to 11th May 2008 (the day the corresponding Rails Envy podcast was recorded).
script/dbconsole
A script/dbconsole script has been added that allows you to connect to your database using its console client.
If you needed to connect to your production MySQL database (you better know what you are doing!), for example, you can run RAILS_ENV=production script/dbconsole and it will login to your database server using the command line MySQL client. This also works with the PostgreSQL and SQLite databases.
To use this script in your Rails app, remember to run rake rails:update:scripts after updating to edge Rails.
This nice little enhancement courtesy of Steve Purcell, who originally had a similar database console plugin.
Related changeset: http://github.com/rails/rails/commit/4a07103687084496b773e18a03b1f2f5e686f7ad
flash.now is now accessible in tests
This is something that many of us Rails developers have probably come across when writing tests for flash messages being set with flash.now, myself included. Basically, you couldn’t test the contents of your flash.now because they were always being emptied before your test could get to them.
# In your controller:
flash.now[:notice] = 'You gotta be kidding me!'
# In your test:
assert_equal 'You gotta be kidding me!', flash.now[:notice]
# FAILS because flash.now[:notice] is nil
Andreas Neuhaus took a good look at how it works and figured out how to make testing flash.now work without resorting to assert_selects.
Related changeset: http://github.com/rails/rails/commit/74eed6290e63111d1aad2b181692a84f4f040aea
There isn’t much else of note so far but if you’d like to know every gritty detail, you’d probably want to peruse the Rails commit logs. As always, let me know of any suggestions or how I can improve the Living on the Edge (of Rails) series.
May 1st, 2008
So we’ve been terribly busy at Bezurk these last 2 months or so working on our new re-branded site with a bunch of new features. We were lucky enough to secure a 4-letter domain name - wego.com (and it came at a price too!) so it was all worth it. Trust me, with a name like Bezurk you’re going to be terribly hard to remember and to brand. We’ve had partners and friends who spell Bezurk in a variety of ways: berserk, bezerk, buzerk. Don’t even ask us about our encounters with non-native English speakers. Don’t.
So yes, the new site: http://www.wego.com/.
We’ve decided to push it “live” as a beta product (and we know it is very much in beta, we’re not kidding or trying to be Web 2.0-ish) prior to our launch party next week. Give it a few hits or so and let me know of any feedback (leaving a comment here is good), especially what annoys you. You might even want to use it to search for airline tickets or to book hotel rooms for your next trip and let us know if we managed to somehow epic fail at the task. If you liked it or booked a trip somewhere, we’re glad to have helped you on your way.
I’d write more about wego.com but what I really wanted to focus on, being a Rubyist and all, is what is really cool to me about wego.com - we’ve rebuilt our Hotels product from the ground up (it was a mostly Java before, and it is still live on http://bezurk.com/hotels/) in 85% Ruby, 8% JavaScript, 5% Erlang, and 2% Java. Well, those are rough figures anyway. We also made a strong effort to keep our mostly AJAX application as usable as possible without JavaScript but I’ll admit, we had to cut some corners due to deadlines.
I’d love to be more specific about the design and architecture of our Hotels application and on the cool stuff (CouchDB, Rack, Solr, jQuery, libmemcached, and of course, Ruby) we’ve used that have made our lives as developers much easier than when we were in Javaland - but I’d leave that for a later post. I’m sure my friend Arun Thampi also has a war story to tell so we’ll come up with something entertaining. Stay tuned!
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.