Dynamic content on static pages through AJAX
Until today I had a problem. Because I have a slow server, some many-to-many relationships in my code design, and some pretty heavy SQL querys some pages here on bottiger.com can be a bit slow to generate. Of course the solution to that problem isn’t buying a better server but do some caching.
Since you don’t see any dynamic content on most of my pages you may think that I would be able to do some page caching for the best result, but unfortunately that’s not the case. I actually do have some dynamic content, though it’s not much :) When I log in a page looks like this:
As you already know Rails has three methods of caching . I was forced to rely on fragment caching which in my opinion is a mess, since you have to cache both the view and the controller. I read many creative solutions to this, like storing the content in a cookie and have a javascript display it, but I think the only decent solution is to provide the dynamic content through an AJAX request. Normally AJAX isn’t a good solution since the user needs to have javascript enabled, and there’s always a small delay on AJAX calls. But since the only victim is me I decided to implement it. If you google on it you wont find much, since all the “AJAX on rails” tutorials out there assume some kind of action—like submitting a form or clicking a link. But this is how I solved it after many hours of reading the docs and talking to people on IRC.
First you need a place to but the content you are going to receive. Lets just put it inside a div
<div id="content"></div>
you can use the helper remote_function to generate the code which performs the AJAX request, but it wont run by itself. To run it you need to pack it into a function and call the function from a update_page_tag block, somewhere in your view.
update_page_tag {|p| p.call "(function(){" + remote_function(:update => 'content', :url => "/admin/menu") + "})" }
The line above will work as it is, but I think it’s worth putting into a helper in application_helper.rb
def remote_update(options = {})
update_page_tag {|p| p.call "(function(){" + remote_function(options) + "})" }
end
This enables you to just call remote_update from anywhere in the view. Since it takes the same arguments as link_to_remote you can either update a specific element with some HTML
remote_update(:update => 'id_of_some_element':url => '/return/some/html')
or just call
remote_update(:url => '/return/some/rjs')and return all the rjs you want







