Rails - How to find out who is online

Posted by matt on December 13, 2006

Well, this is my first post. I was frustrated in to starting this blog, through searching the internet for solutions to various programming problems, and finding either nothing, or only half the answer. Hopefully I will be able to help others solve some of their problems faster. Recently I have been writing a dating site in ruby on rails. One quite important feature of this site is a list of members who are currently online. After a couple of days of pain, here’s the pretty simple solution to the problem:

First off this only works if you use ActiveRecord to manage your sessions. To do this you must uncomment the following line in your environment.rb file:

config.action_controller.session_store = :active_record_store

Then create the sessions table by running the following command from your RAILS_ROOT:

rake db:sessions:create

Now, whenever a user logs in to your application add their id to the session. In my app at the moment it looks something like this:

member = Member.new( @params[ :member ] )
member = Member.find( :all, :conditions => "screen_name = '#{member.screen_name}' AND password = '#{member.password}'" )
if member != nil
  session[ :member_id ] = member.id
  redirect_to :action => 'success'
else
  redirect_to :action => 'form'
end

This code will need work for a production environment, for one thing it is open to SQL injection attacks.
Now to find all of the users who are currently online it is just a matter of searching the sessions table for all the users who have been active in the last 10 minutes. This can be done using rails built in session model. Finally the session data needs to be unmarshaled and decoded. This stumped me for a while, but finally I found the answer at http://caboo.se/doc/classes/CGI/Session/ActiveRecordStore/SqlBypass.html. So here is my code to return an array of the member_ids of all the members online and active within the last 10 minutes.

def who_is_online
  @whos_online = Array.new()
  onlines = CGI::Session::ActiveRecordStore::Session.find( :all, :conditions => [ 'updated_at = ?', Time.now() - 10.minutes ] )
  onlines.each do |online|
    id = Marshal.load( Base64.decode64( online.data ) )
    @whos_online << id[ :member_id ]
  end
  return @whos_online
end
Trackbacks

Use this link to trackback from your own site.

Comments

Leave a response

  1. dahuk Mon, 18 Dec 2006 11:16:22 GMT

    Thanks for the help

  2. […] matt-beedle.com » Rails - How to find out who is online (tags: online rails Ruby) […]

  3. Caiwangqin Mon, 16 Apr 2007 07:03:16 BST

    i am used rails 1.2.2, but i got error with who_is_online method:

    undefined method `unpack’ for { :user=>2, “flash”=>{}, :return_to=>”/”}:Hash

    could you know how to fix this?

  4. VzMind Thu, 10 May 2007 09:33:36 BST

    does anyone sole this unpack pb? I am also facing the same error and it’s very hard to find some info about that on the web.

  5. VzMind Thu, 10 May 2007 10:45:22 BST

    ok I have done that:
    @whos_online
    and it's working.
    In fact I dont understand the use of this marshal.load....

  6. bogn Thu, 26 Jul 2007 21:14:23 BST

    Hi, seems like a short and simple approach. But I went into two problems. At first it took me some time to recognize why I never get a single session object. This condition you have there is ‘updated_at = ?’, shouldn’t it be ‘updated_at > ?’, because it’s close to impossible to have one session updated at EXACTLY one timestamp. I couldn’t fix the second problem, which is the same one that Caiwangqin and VzMind faced. It would be really great if someone described VzMind’s solution or an other one.

  7. Alfred Toh Thu, 09 Aug 2007 03:53:05 BST

    The error undefined method `unpack’ for { :user=>2, “flash”=>{}, :return_to=>”/”}:Hash is due to the code using

    id = Marshal.load( Base64.decode64( online.data ) )
    instead of
    id = Marshal.load( Base64.decode64( online[’data’]) )
    since the return data is a hash array and not an activerecord model

  8. Manik Thu, 25 Oct 2007 11:13:19 BST

    Nice Tip.
    Thanks

  9. […] 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 […]

  10. Bill Harding Mon, 28 Jan 2008 10:50:03 GMT

    Great starting guide!

    I fixed a couple errors in the above, went into a few more specifics in getting it set up, and describe an implementation that doesn’t need to get mixed up with the performance inefficient-Marshalling stuff:

    http://www.williambharding.com/blog/?p=99

Comments