# HeartbeatFor module HeartbeatFor def self.included(controller) controller.extend(ClassMethods) end module ClassMethods # updates a datetime column for a model every N minutes # # usage: # (app/controllers/application.rb) # heartbeat_for :current_user # # or optionally specify the column name and interval: # heartbeat_for :current_user, :last_seen, 5.minutes # # model_method: # the method to return the model that you wish to check, # e.g. :current_user # # heartbeat_method: # the model's datetime column to store the heartbeat, # defaults to :last_activity # # interval: # the interval in seconds to update the heartbeat, # defaults to two minutes def heartbeat_for(model_method, heartbeat_method=:last_activity, interval=2.minutes) @_heartbeat_for_models ||= {} unless @_heartbeat_for_models.key?(model_method) @_heartbeat_for_models[model_method] = { :heartbeat => heartbeat_method, :interval => interval } end before_filter do |c| @_heartbeat_for_models.each do |model_method, props| model = c.send(model_method) # failsafe if model_method returns nil next unless model && model.respond_to?(props[:heartbeat]) now = Time.now.utc key = "#{model_method}_last_activity" if c.session[key].blank? || (now - c.session[key]) > props[:interval] c.session[key] = now model.send("#{props[:heartbeat]}=", now) model.save end end # each end # before_filter end # heartbeat_for end # ClassMethods end