Using AJAX to load Rails partials
I had an excuse recently to try something I thought was going to be trivial, what with all the kids using AJAX these days. Unfortunately since I wasn’t trying to create another live search feature, documentation, blog postings and several books on the subject were surprisingly lacking.
See, all I was trying to do was to load a page fragment, or partial in rails speak, in an asynchronous way. While this doesn’t sound very glamorous, its a great way to make your web application feel more responsive when you have a particularly heavy weight partial to deal with.
An Example:
A page within your web application displays your site layout, a menu or two, some paginated flummoxes, topped with a lovely, glass like logo that is showing it’s bright and shiny reflection on some strange surface that shields your website from anything that might fall from the address bar.
Toward the bottom of the page, you display some recommended flummoxes, based on whatever flummoxes the user has visited recently. (As you can surely tell, this example is not only made up, but is quite far from the more complex scenario that led me down this path in the first place. As we know, creating example code is a PITA.) This recommendation flummox feature is a real drag. It can take seemingly forever to render since it involves a few complex queries, and of course a REST call or two. Wouldn’t it be great if you could render the whole page, minus the flummox recommender, and have that feature filled in once it responds? Exactly.
The Call to Action
Note that this request is (likely) handled by a BrowseController. The important thing to realize is that we need to pull out the slow, heavy logic that would normally drive the content in that slow flummox recommender feature and put it elsewhere. In our example, we’ll pull it out into its own, new controller.
The Controller
Here we have our controller, which will coordinate our requests to our model, as well as make a web service call or two:
Notice that render line? We’ll come back to that in a minute.
The View
index.html.erb (This is rendered by the original call to BrowseController, our otherwise fast loading page.)
Aha! There’s our AJAX! You’ll notice that I have to actually type some JavaScript there. I am alive to talk about it, but I sure don’t like to dirty my hands in it. If this pattern seems useful to folks, I may try to submit a patch to one of the rails helpers (JavaScript or Prototype helper) to make this a bit less dirty.
So what are we doing there? We’re creating a new Ajax.Request, thanks to our beloved Prototype JavaScript library, and feeding it a URL to request via a GET method. We can use the url_for helper to clean that up a bit, so it’s not too nasty.
Our erb partial:
You’ve probably already built the code for the partial that displays those flummox recommendations, right? Notice that @type variable in our controller? We set that to “name_of_real_partial_to_load”, so let’s create app/slow/_name_of_real_partial_to_load.html.erb
Great, but how do we get that to render? We made a call to load “load” from the super_slow_action_call action in our SlowController!
Our RJS View, the glue to load them all!
app/slow/_load.rjs
Here, we’re inserting our partial (@type), into a div by the same name (@type), within the original view serving the request.
Since it is such a slow loading page fragment, we mine as well draw some attention to it once it gets there, so we’ll highlight it using our dear friend script.aculo.us.
So there you have it. Render a slow-loading partial in your Rails application, using AJAX.
Note:
Admittedly this pattern takes a bit of elbow grease to build out. If you have alternative suggestions, aligning more closely with The Rails Way, please let me know. If this pattern seems to mass the muster however, I’ll consider appending to one of the existing helpers to facilitate the Ajax.Request bits, to make this a little smoother.
Comments
7 Responses to “Using AJAX to load Rails partials”
Leave a Reply

I usally do things like that this way:
load
…
//jQuery
$(’div.heavy a’).each(function(){
$(this).parent.load($(this).attr(’href’));
});
ym2c
hope your comments can handle html, or it will look..messy :D
hope this looks better…
<div style=”display:none”>
<div class=”heavy”>
<a href=”heavy_data_url”>load</a>
</div>
…
</div>
<script>
//jQuery
$(’div.heavy a’).each(function(){
$(this).parent.load($(this).attr(’href’));
});
</script>
Having never tried it, but I mirrored grosser’s thoughts while reading the article. Having recently switched over to jQuery for everything RJS, ajax-life is much nicer.
The problem though, is there is no progressive-enhancement feature of this page. It’s either ajax-or-nothing.
Everything I can come up with off the top of my head would be a hack, anyone think of a way around this?
another convertee :D
tried jrails yet ?
Maybe the best solution therefore would be to not hide the links, so when something goes ajaxy wrong they will still be there and can be used normally
Grosser, just to clarify, there are no links in this example.
This is one of the primary differences between this pattern and examples found in all the books.
The user takes no action, be it submitting a form or clicking a link, to cause these fragments to be loaded. They are page fragments that would typically be rendered normally, as part of the current view.
yep, the links i used are only there to leave something for the spiders to follow, normally no one will see em
Exactly what I needed, thanks!
I was running into token authenticity issues when I was trying this myself, but the url_for got me through it.