I\'m using devise which stores current_sign_in_at
and last_sign_in_at
datetimes.
But lets say a user logged in a month ago but last vie
How about this:
Create a migration to add a new field to users to store the date and time the user was last seen:
rails g migration add_last_seen_at_to_users last_seen_at:datetime
Add a before action callback to your application controller:
before_action :set_last_seen_at, if: proc { user_signed_in? }
private
def set_last_seen_at
current_user.update_attribute(:last_seen_at, Time.current)
end
This way, on every request (i.e. activity) that the current user performs, his/her last seen at attribute is updated to the current time.
Please note, however, that this may take up some of your app's resources if you have many users who are logged in, because this will execute before every controller action requested by someone who is logged in.
If performance is a concern, consider adding the following throttle mechanism to step 2 (in this example, throttling at 15 minutes):
before_action :set_last_seen_at, if: proc { user_signed_in? && (session[:last_seen_at] == nil || session[:last_seen_at] < 15.minutes.ago) }
private
def set_last_seen_at
current_user.update_attribute(:last_seen_at, Time.current)
session[:last_seen_at] = Time.current
end
To improve performance of the previous answer:
update_attribute
runs callbacks and updates updated_at
attribute, and update_column
notUpdated code:
before_action :set_last_seen_at, if: proc { user_signed_in? && (user.last_seen_at.nil? || user.last_seen_at < 15.minutes.ago) }
private
def set_last_seen_at
current_user.update_column(:last_seen_at, Time.now)
end
Devise plugin makes similar behaviour happen (just last seen, without optimizations): https://github.com/ctide/devise_lastseenable