4

I have a Rails application using Devise for authenticate users but I want track the time for users online in the platform. I would like have a column in user table which save the time online for this user (hours, minutes..). For example, one user was online 2 hours in total, another user 15 minutes...

Does exist some gem or Devise method for this functionality?

Thanks in advance.

  • You could send an AJAX request the server every 1 second to update the 'time online'. Make sure that the server doesn't allow the request to succeed more than once per second. – max pleaner Jul 17 '17 at 18:26

2 Answers2

2

Since DEVICE stores last_sign_in_at as soon as a user login in to the account and becomes online.

You can do something like this.

Add a migration to change users table and add a field, total_online_time

rails g migration add_total_online_time_to_users total_online_time:Float

Add a before action callback to your application controller to check user actions:

before_action :set_online_time, if: proc { user_signed_in? }

In this method, I will get last_sign_in_at and as I have current time, I will get the difference of these times and store in the DB as minutes and seconds.

Again, if he login, I will add this time to old time.

Currently I am saving the minutes and seconds. Since I can't directly add two times.

EDIT:

I am saving in minutes because, if we save string or time in Database, we cannot add the last value plus the current value on the go. So it the case.

def set_online_time

  start_time = current_user.last_sign_in_at.to_time;
  end_time = Time.now;

  if(start_time && end_time)_
      minutes = time_diff(start_time, end_time)
      if(current_user.total_online_time)
        minutes = current_user.total_online_time + minutes
      current_user.update_attribute(:total_online_time, minutes)
  end  

end

HEre is the method to manipulate time:

private


def time_diff(start_time, end_time)
    (start_time -  end_time) / 60
end

Now, retrieve the minutes from DB and convert to HH:MM:SS

Hhere is the method for that ,

Time.at(seconds).utc.strftime("%H:%M:%S")

So, Time.at((current_user.total_online_time) * 60).utc.strftime("%H:%M:%S") is yours.

HERE IS AN EXAMPLE:

time1 = Time.now   => 2017-01-27 18:01:42 +0530

time2= Time.now - 4.hours  => 2017-01-27 14:02:02 +0530

minutes = time_diff(time1,time2)  => 239.66325946553334

Time.at((minutes) * 60).utc.strftime("%H:%M:%S") => "03:59:39"

So, "03:59:39" is the online time.

Note:

1) This answer keeps on incrementing the online time of the user whenever he logs in.

2) If you want only the last time, just use,

minutes = time_diff(start_time, end_time)
current_user.update_attribute(:total_online_time, minutes)

You can also take an extra field and save current online time.

Sravan
  • 16,897
  • 2
  • 24
  • 48
1

You can just add two fields to your user table: last_login_time and hours_logged. Whenever the user logs in, you save its time on last_login_time. And whenever the user logs out you calculate the total time spent and adds to hours_logged.

To do this you can override devise controller methods and add these tasks. This other QA says more about that.

Community
  • 1
  • 1
Rafael Costa
  • 957
  • 1
  • 9
  • 22