posted: May 13th, 2007 · by: Sven
Originally triggered by Jeremy Hubert I’ve posted some thoughts about more concise and transparently localized Rails url_helper methods last month.
Basically Jeremy nailed a problem that occurs as soon as you define a Rails route that includes the locale as the leftmost parameter: you now can’t use Rails’ url_helper methods in a reasonable DRY way any more! A reasonable solution was pending.
Plugins to the rescue. By the end of this article you’ll be able to choose between two different solutions to this problem.
For example you might have defined a route like this:
Or with Rails’ RESTy resources:
map.resources :articles, :path_prefix => ":locale"
How would you now use url_helper methods without specifying the locale every single time you’re calling an url_helper? You can’t. Without any further efforts you’d have to say, e.g.:
instead of being able to just use:
And the latter clearly is what one would expect from a Rails solution, isn’t it? It is.
There are two different solutions to this problem (that I know of, of course):
With respect to the problem at hand and their solution to it they both have quite something in common: Both of them achieve largely the same, particulary both provide a reasonable flexibility concerning the Rails url_helpers that triggered this quest. Both of the solutions are available as plugins and are installed super-easily. Both are quite young, too.
On the other hand they both take a pretty different route to solve our problem and thus, there’s a series of difference too, of course. Let’s see …
The resource_fu plugin
I hope that I get things right when I say that
ressource_fu basically does two things and thereby solves our original problem:
- Most importantly it tries to “guess” (or “infer”) parameters that you haven’t passed to your url_helper, but that are necessary to build the URL. E.g., when you ommit the :locale parameter, it looks for a (controller) instance variable with the same name.
- Secondly it “anchors” positioned arguments on the right side. That means that if your route has three segments and you only supply two positional arguments, the url helper assumes you are supplying the *last* two segments.
This way both of these will work as long as you have defined a controller instance variable
@locale (from which the parameter will be “inferred”):
article_path(@article) # positioned arguments article_path(:id => @article) # verbose hash syntax
Hurray. Mission complete!
Resource_fu has more benefits than this. Read more about it in its readme file. You can download/install the
resource_fu plugin from here:
The localized_url_helper plugin
localized_url_helper plugin tackles things seperatly and targeted:
- For the hash argument syntax it will smuggle the locale past the Rails routes’ “parameter expiry” mechanism. It thereby tricks Rails into simply using the locale parameter and then proceeding as if it wasn’t there at all.
- For the positioned argument syntax it’s sufficient to just push the locale onto the front of the arguments list.
Two very simple steps and that’s it.
You can download/install the
localized_url_helper plugin from here:
Which solution should you choose?
I really don’t know :)
Both plugins achieve largely the same thing with respect to this problem but they are using two quite different approaches. Even at this microscopic scale there’s no silver bullet, I guess. Look at the differences.
Resource_fu does more than just solving the original problem - and it is designed to do so. The main selling point of
resource_fu is: it changes the way url helpers behave. In my personal opinion it does this in a very elegant, reasonable and useful way. Check it out! If that’s what you want (and if you’re probably starting a new project so don’t have to double-check all your url_helpers)
resource_fu definitely is for you.
Localized_url_helper on the other hand is probably more of the laser-scalpel type of tool. It solves exactly the problem posed above and nothing else. Also it’s quite a bit less code and it’s coded as unobtrusive and careful as possible (as far as I can tell, that is). So it probably is a bit less prone to breakage through changes in future Rails updates.
Actually I learned about
resource_fu after I’ve presented the first version of my plugin to the Globalize developers list.
I probably wouldn’t have started trying to come up with my own plugin at all if I would have known about Trevor’s
resource_fu in the first place. But digging through the Rails routing code and trying to patch it to behave the way I wanted has been pretty instructive. I can only recommend that!
Anyways I think the results have been worth it: at the end of the day we can now choose between to solutions when it comes to localize our routes and keep our URL helpers DRY at the same time. :-)
What do you think?