Extending render
Yesterday’s tip demonstrated how to refactor common RJS bits into their own method. Specifically, it gave an example that created a special render_error
method which you can call whenever you need to render an error.
Today’s tip is about overriding the existing render
method, to add support for your own custom conditions. Specifically, render_error
is nice and all, but wouldn’t it be nice to make it look more like the standard Rails render
method?
1 2 3 4 5 |
def create ... rescue Exception => error render :error => error end |
It’s remarkably simple, actually. To implement the above, you’d just throw something like the following in your ApplicationController:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
def render(*args) if args.length == 1 && args.first.is_a?(Hash) case args.first[:error] when nil then super when ActiveRecord::InvalidRecord render(:update) do |page| page[:js_error_bold].replace_html(args.first[:message]) page[:js_error_text].replace_html( args.first[:error].record.errors.full_messages.join("\n")) page[:js_error].visual_effect :blind_down, :duration => 0.2 end else raise args.first[:error] end else super end end |
In other words, first we check to see if the first and only argument is a hash (since that’s all our new feature uses). Then, we test the value of the :error
key, calling super whenever we want to delegate to Rails’ render
method. We then compare the error raised to some list of errors that we want to handle specially, and do the appropriate work for each.
You could also make it so that it accepted the error directly, as the first argument (render(error)
).
You can use this technique anywhere you find yourself rendering the same kind of thing in multiple places. Errors are a good example, and are (frankly) where I use this technique the most.
Reader Comments
That’s pretty neat. I tend to do a similar thing with find on ActiveRecord:
16 Jan 2007
Ryan, nifty! Be careful, though, of forcing an order like that, because unless ‘name’ is part of every index you use, your database is going to hate you. ;) Sorting cannot be done efficiently in the database unless the sort key(s) are part of the index that was used to satisfy the query.
16 Jan 2007
Jamis, that is very cool – thanks for the tip a day!
—Zack
16 Jan 2007
Of a somewhat related nature, we created and have been using this plugin:
http://code.inklingmarkets.com/pretty-flash/
If you want to see it in action, just trying and login to http://home.inklingmarkets.com with some random user/pass.
It basically hijacks all uses of flash[:notice] and flash[:error] and throws up a pretty cool box at the bottom (A little green for notices and a little red for errors). It was heavily inspired by the flash notices and errors from Shopify. And I wanted to get it so that it was just an easy drop in plugin without having to change any of my flash[:error] calls to something else.
But it looks like I could make it much niftier and maybe a bit less hackish with this tip.
16 Jan 2007