Ajax Spy in Rails
I was playing around with Digg this morning and noticed Digg Spy. At first I thought it was really cool and wondered how they did that. Then I realized it’s just a bit of Ajax and, as anyone who’s read Pragmatic Ajax knows, Ajax is easy! So read on for how I implemented an Ajax spy in Rails and to download the code.
The first thing I did was generate a controller and model using Rich White’s excellent AjaxScaffold Generator, called EntriesController and Entry, respectively. This gave me a nice way to create new entries easily. After that I added some basic login/signup support so that the entries could be associated with users. So far, nothing out of the ordinary.
Next I created a new controller called SpyController, this is where all of the action happens. I added a basic list method which just returns all of the entries in the DB (sorry, no pagination), this is what we initially call when displaying the page. Then I added an update method which will be called periodically to retrieve new entries, it looks like this:
-
def update
-
last_update = Time.parse(params[:timestamp])
-
# locate all of the entries created since the last update
-
@entries = Entry.find(:all, :order => ‘created_at ASC’, :conditions => [ ‘created_at > ?’, last_update.to_s(:db) ]);
-
if !@entries.empty?
-
render :update do |page|
-
for entry in @entries
-
page.insert_html(:top, ’spy-list’, :partial => ‘entry’, :object => entry)
-
page.visual_effect :highlight, "spy-item-#{entry.id}"
-
end
-
end
-
end
-
end
At this point I needed some JavaScript to call the update method, so put the following code in application.js:
-
var updateInterval = 5000; // update every 5 seconds
-
var timestamp = new Date().toUTCString();
-
var timer;
-
-
function go() {
-
timer = setInterval(‘update()’, updateInterval);
-
}
-
-
function update() {
-
url = "/spy/update";
-
new Ajax.Request(url, {
-
asynchronous: true,
-
method: "get",
-
parameters: "timestamp=" + timestamp,
-
onSuccess: function(request) {
-
timestamp = new Date().toUTCString();
-
}
-
});
-
}
The JavaScript update method calls the SpyController’s update method and passes a timestamp as a parameter (this is the time when the page was loaded, initially, and later the timestamp is updated as new entries are retrieved). To bring it all together I had to add on onload to the list.rhtml view for the SpyController, like this:
-
<body onload="go()">
-
<p>This page updates automatically!</p>
-
<br/>
-
-
<div id="spy-list" class="spy-list">
-
<% if !@entries.empty? %>
-
<%= render :partial => ‘entry’, :collection => @entries, :locals => { :hidden => false } %>
-
<% end %>
-
</div>
-
</body>
That’s all there is to it. See, I told you it’s easy! You can download the code from here (Updated for Rails 1.2.3).
Add New Comment
Viewing 2 Comments
Thanks. Your comment is awaiting approval by a moderator.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Add New Comment