module ActivityTracker # :nodoc:
def self.included(base) # :nodoc:
base.extend ActMethods
end
module ActMethods
# Arguments:
# :actor - the user model that owns this object. In most cases this will be :user. Required.
# :options - hash of options.
#
#
# Options:
# :if - a Proc that determines if the activity should be tracked.
#
# Examples:
# acts_as_activity :user
# acts_as_activity :author
# acts_as_activity :user, :if => Proc.new{|record| record.post.length > 100 } - will only track the activity if the length of the post is more than 100
def acts_as_activity(actor, options = {})
unless included_modules.include? InstanceMethods
after_create do |record|
unless options[:if].kind_of?(Proc) and not options[:if].call(record)
record.create_activity_from_self
end
end
has_many :activities, :as => :item, :dependent => :destroy
class_attribute :activity_options
include InstanceMethods
end
self.activity_options = {:actor => actor}
end
# This adds a helper method to the model which makes it easy to track actions that can't be associated with an object in the database.
# Options:
# :actions - An array of actions that are accepted to be tracked.
#
# Examples:
# tracks_unlinked_activities [:logged_in, :invited_friends] - class.track_activity(:logged_in)
#
def tracks_unlinked_activities(actions = [])
unless included_modules.include? InstanceMethods
class_attribute :activity_options
include InstanceMethods
end
self.activity_options = {:actions => actions}
after_destroy { |record| Activity.destroy_all(:user_id => record.id) }
end
end
module InstanceMethods
def create_activity_from_self
activity = Activity.new
activity.item = self
activity.action = self.class.to_s.underscore
actor_id = self.send( activity_options[:actor].to_s + "_id" )
activity.user_id = actor_id
activity.save
end
def track_activity(action)
if activity_options[:actions].include?(action)
activity = Activity.new
activity.action = action.to_s
activity.user_id = self.id
activity.save!
else
raise "The action #{action} can't be tracked."
end
end
end
end