pseudofish

powered by text files

programming

Tracking Outbound Links with Rails 3

To gain some insight on what interests users, I want to be able to track which links they click on.

There were a number of options I considered, and finally settled on using Javascript to update an underlying Click model. For analytics, I intend to aggregate the data offline. Thus the current aim is capture only.

To store the data, I created a simple model using:

rails g model Click url:string request_ip:string user_agent:string user_id:string

I decided not to store the all the request data, and instead just track the following:

Rails kindly adds in the created_at column, which is the final key piece of data.

To generate the click data, I added the following into my application.js:

$("a").live("click", function() {
    params = { click: { url: this.href } };
    $.post("/clicks", params);
    setTimeout('document.location = "' + this.href + '"', 100);
    return false;
});

This posts the click through to the Click controller. In the controller, I added in the following:

def create
    @click = Click.new(params[:click])
    @click.request_ip = request.remote_addr
    @click.user_agent = request.user_agent
    @click.user_id = cookies[:uid]

    respond_to do |format|
        if @click.save
            format.js { render :json => @click }
        else
            format.js { render :json => @click.errors }
        end
    end
end

To generate the tracking cookie, I included the following in application.js:

if($.cookie("uid") == null) {
    var tracking_id = $.md5($.now() + "-" + Math.ceil(Math.random() * 314159)); // Current time + random seed
    $.cookie("uid", tracking_id, { expires: 365 * 20, path: "/" });
}

By using an MD5 hash of the current time and a random number, I am comfortable enough that it is unique enough for tracking purposes.

In this example, I am tracking all clicks on the application. For production use, I’ll filter this down to only the outbound article titles.

I’ve included a skeleton Rails 3 app that includes the code on GitHub. I used a jQuery plugin for cookies and MD5 hash generation, and these are included in the public/javascripts directory.

There are a few things that this misses, such as links clicked via RSS, via Twitter, and a heap of tests. I’m looking into Feedburner and bit.ly to see if I they fill in the missing metrics.