17 November 2006
RJS templates without the R!
In terms of making AJAX applications easier to develop, RJS templates are one of the most significant additions to Rails over the past year. They were far more elegant than adding AJAX callback hooks throughout your main RHTML templates (which was just plain ugly) and it let you get access to your model data in your JavaScript response easily. For many, the killer feature was being able to write your AJAX response behaviour in Ruby—one language to rule them all. The forthcoming Simply Helpful plugin takes this even further. However, not everybody is as keen on RJS templates and a new plugin by Dan Webb seeks to change the way you write your AJAX functionality in Rails.
Dan and I have had several discussions over a few beers about RJS and Dan being the JavaScript wizard that he is was of the opinion that writing JavaScript behaviour in Ruby was an abstraction too far. His reasoning was simple: JavaScript when used correctly can be a powerful language and adding a Ruby API on top was an extra layer of magic that just wasn’t necessary. Whilst he made a fair point, I still felt that RJS was infintely better than the old way of doing things and that its pros outweighed its cons…until now.
The main con with RJS is that you are depending on another layer and if that layer isn’t complete you have to revert to JavaScript anyway—you can do this in RJS by using page.call but this is ugly and really highlights its shortcomings. It would probably be fair to say that RJS as it is currently implemented, is a leaky abstraction. Not only that, but RJS is tightly coupled to the Prototype JS library and Scriptaculous – for fans of one of the many other JS core/effects libraries out there you are left with either the option of trying to port RJS to your library of choice, using page.call commands or resorting to the old callbacks method.
I was somewhat blinded by the “cool” factor of writing my JS behaviours in Ruby—after all I’m a Ruby programmer first and a JavaScript guy second. But when I really think about it, all RJS does is limit me when I want to do anything outside the simple cases that RJS caters for. But the idea of returning a behavioural response from a template is an excellent one and that has always been the overriding factor for me.
As of today, a new option has become available in the form of a new plugin courtesy of Dan – MinusR: RJS templates, without the R! Thats right, RJS templates that let you write your behaviour in JavaScript instead of Ruby. Not only that, but you can still get access to your model data (or other things such as helpers) by embedding ERb—MinusR comes with a js() helper method that encodes the output of your ERb output block in JSON. And finally, you can use whatever JS library you like.
So check it out and start embracing JavaScript. Also check out Dan’s blog post about MinusR.
Return to home page | Check out my tumblelog
3 Comments on this article
Return to home page | Check out my tumblelog
Commenting on this article is now closed
1. Comment by Josh Adams on 18 Nov 2006 at 05:11
Page.call? Come on, the RJS Proxies will work for any javascript classes :) I just use the proxy, write a javascript, and call it a day…
2. Comment by DHH on 19 Nov 2006 at 06:11
As I said on Dan’s page, I think this is good experimentation and there are times where the trade-offs of RJS are not right. We’ve never wanted RJS to be a 100% solution. Just about nothing in Rails is. Same goes for Active Record, which you could well bill a leaky abstraction on top of SQL. That’s fine. Leaky is good, leaky works. We’re simply trying to trivialize the 80% case so you can work your manual magic on the last twenty.
Keep the prize in mind.
3. Comment by Peter Michaux on 26 Nov 2006 at 06:11
Hear, hear!
Wrapping JavaScript in Ruby was a bad idea. Developing diverse, rich JavaScript pages requires far more options than the mechanical SQL that Active Record generates for the RDMS. If Prototype bloats to the size of Active Record to accomadate a bigger subset of the possible options that wouldn’t be good for server loads.