The maze book for programmers!
mazesforprogrammers.com

Algorithms, circle mazes, hex grids, masking, weaving, braiding, 3D and 4D grids, spheres, and more!

DRM-Free Ebook

The Buckblog

assorted ramblings by Jamis Buck

Inline RJS

10 January 2007 — 1-minute read

We all know and love RJS templates in Rails. (If you don’t, please do google them and read up—you’re missing out on some of the hottest stuff around.). I honestly believe they are the most significant advance in web development technology since the introduction of XmlHttpRequest.

Sometimes, though, it seems like a bit of overkill to have to create a new file if all you’re doing is highlighting some element, or removing one. If your action only responds to “text/javascript” requests, it’s often much simpler just to inline the RJS calls, right there in your controller:

1
2
3
4
5
6
7
class ItemsController < ApplicationController
  def destroy
    @item = current_account.items.find(params[:id])
    @item.destroy
    render(:update) { |page| page[dom_id(@item)].remove }
  end
end

(Note that the dom_id helper is courtesy of the simply_helpful plugin.)

That call to render(:update) just yields the RJS page instance to the block. Then, you can do all your RJS calls in the block, instead of having to create a file for a single line of code.

When would you not want to do this? Well, if your RJS stuff is particularly complex, or does more than a handful of things, you might be better off throwing it in its own template. Also, if your action responds to more than just RJS (e.g., via the respond_to method), you should use a separate RJS template file as well.

Reader Comments

Thanks for the tip. I often end up being confused by all these little RJS-templates. I believe this is much clearer, although a bit of a sacrifice on MVC.

“although a bit of a sacrifice on MVC.”

Perhaps. But perhaps not. In my mind, RJS templates are not “the view”—they are mini programs that define how you want to manipulate the view. And that sounds a lot more like a controller than a view, to me.

I’ll admit, though, that’d I’d rather see individual RJS template files in the view directory than in the controller directory.

Jamis, is render(:update) a recent addition to edge or did it come in w/ the rjs stuff?

Been there for a long time now. I noticed inline RJS in the Opinion SVN repository (message board created by leetsoft) many months ago.

I use this approach almost exclusively. I find it much easier to keep track of what is going on.

Simply helpful implicitly calls dom_id on active record objects passed to the [] method so you simplify the render call to:


render(:update) { |page| page[@item].remove }

Doh, thanks Myles. :) You sure can.

Thanks, Jamis, for the posts. They’re always enlightening. To second your post above, I completely agree with putting RJS in the controller instead of its own file—unless it’s very long, or several methods are sharing the same RJS file and explicitly calling it, it’s just another file to keep track of.

And since the call to the RJS file doesn’t have to be explicit, it’s not obvious from looking at the controller whether a particular method is calling an RJS file or not. So I found myself checking my filesystem to see if there was an RJS file with that method name that was being called. So in the end, it created more work for me than just including the RJS code right in the method.