44

Using Devise on Rails, is there some way to list all the users who currently have active sessions i.e. the users that are currently logged in?

Ps. I'm looking for a robust solution, not something simplistic like the ones in this question

Community
  • 1
  • 1
Zabba
  • 64,285
  • 47
  • 179
  • 207
  • I found this answer very useful: http://stackoverflow.com/questions/20821341/rails-how-to-show-users-last-seen-at-time – rassom Feb 21 '14 at 09:39

5 Answers5

87

Simply add after_filter in ApplicationController

after_filter :user_activity

private

def user_activity
  current_user.try :touch
end

Then in user model add online? method

def online?
  updated_at > 10.minutes.ago
end

Also u can create scope

scope :online, lambda{ where("updated_at > ?", 10.minutes.ago) }
Yuri Barbashov
  • 909
  • 1
  • 6
  • 2
  • Would devise_lastseenable still work with rails 3.2 and Devise 2.0? – Rubytastic Feb 06 '12 at 15:45
  • 1
    @Rubytastic I don't know, but this solution is so simple I'd rather use it than add extra dependencies which could break in future releases of rails or devise. – Zubin Feb 24 '12 at 04:20
  • 12
    Isn't this going to run SQL on every action? – Noz Feb 14 '13 at 18:49
  • 21
    This was a great suggestion. Because touch sets the updated_at column, it could produce a false positive if you use the general column updated_at to see who is online. For example, adjusting someone's user profile would falsely show them as online for 10 minutes. We used current_user.try(:touch, :last_response_at) and added this new field to the database with a migration. We also set this to nil on sessions#destroy so they drop out anytime the user explicitly logs out. Last but not least, we made sure to add an index for the new field. – Charles Forcey Mar 20 '13 at 13:23
  • I like this solution, but I'm a bit confused on implementing it. If I'm trying to determine if the current_user is online (say they had multiple tabs and logged out on one of them), is there a way to use this without refreshing the page? – Kyle Bachan Jun 18 '14 at 21:42
  • @yuribarbashov how does that compare to this? http://www.ryanepp.com/blog/how-do-i-tell-if-a-user-is-online – MicFin Nov 10 '14 at 01:25
25

https://github.com/ctide/devise_lastseenable

You can use this gem that I wrote to store the 'last_seen' timestamp of a user. From there, it's pretty trivial to display the users who were last_seen in the last 5 or 10 minutes.

ctide
  • 5,217
  • 1
  • 29
  • 26
20

If you're bothered by making a trip to database on every. single. http. request. only to have some small window where you can sort of assume that a user is online; I have an alternate solution.

Using websockets and redis it's possible to reliably get a user's online status up to the millisecond without making a billion costly writes to disk. Unfortunately, it requires a good bit more work and has two additional dependencies, but if anybody's interested I did a pretty detailed write here:

How do I tell if a user is online?

Ryan Epp
  • 931
  • 1
  • 10
  • 21
1

I've just implemented another version of this and thought I'd share in case it helps anyone else.

I just add a last_sign_out_at column to my Users table and then subclassed the Devise sessions controller so I could override the destroy method to set it when the session is destroyed (user signs out):

# app/controllers

class SessionsController < Devise::SessionsController

  def destroy
    current_user.update_attribute(:last_sign_out_at, Time.now)
    super
  end

end

And then in my User model I have a method to check if the user is online:

class User < ActiveRecord::Base

  def online?
    if current_sign_in_at.present? 
      last_sign_out_at.present? ? current_sign_in_at > last_sign_out_at : true
    else
      false
    end
  end

end

Also you need to tell Devise to use the new Sessions controller in your routes.

mchapman17
  • 53
  • 4
  • 5
    This is not a very good solution (at least not alone), as most user won't sign out, just close the browser or leave the site. – jokklan Dec 02 '13 at 15:39
0

We can list the current active sessions using the active record session store. Please look at the github app page https://github.com/mohanraj-ramanujam/online-users.

Mohanraj
  • 4,056
  • 2
  • 22
  • 24