Rails Track Online Users through Session

We recently needed to implement tracking which users are online at our site. Matt Beedle posted a good starting guide to how to do this, but I found that there were a possible improvements from his tutorial.

Like Matt, we’re using an ActiveRecord session store to track who’s online when. Unlike Matt, we wanted to keep track of when the user last accessed a page, and what page they accessed. The most SQL-efficient way I could find to do this was to add fields directly to the session model and update those. To add the fields to the model, I just created a migration that added the stuff I wanted to track:

add_column :sessions, :user_id, :integer
add_column :sessions, :last_url_visited, :string

Next, I created a before_filter in our application to update these as the user moved through the site, like so:

session.model.update_attribute(:user_id, session[:user_id])
session.model.update_attribute(:last_url_visited, request.url)

With these properties getting updated, all that remained was to write a query to figure out who’s been moving around the site recently. This ended up being as simple as:

online_sessions = CGI::Session::ActiveRecordStore::Session.find( :all,
:select => "user_id, last_url_visited",
:conditions => [ "updated_at > ? and user_id is not null", Time.now() - 30.minutes ],
:limit => 50 )

And that was about it. The tracking is just one SQL UPDATE a pop, and the session find doesn’t need any fancy joins and such, so it ought to scale pretty well.

6 Replies to “Rails Track Online Users through Session”

  1. Not a good solution since exposing the user_id in the session constitutes a security breach…
    Better add fields on the user model…

  2. Why add to the session table? If your goal is to find out who is online and what url they last visited why not just add a last_url field to the user model and update that in your before filter, then do something like

    User.find :conditions => [“updated_at > ?”, Time.now – 1.hour]

  3. I should mention that if you do this and you’re doing any clever after_save filters it’s important to optimize them. I was generating a profile header image with Image Magick on each save which was making things rather slow.

Leave a Reply

Your email address will not be published. Required fields are marked *