action_tracker.rb
5.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
require File.join(File.dirname(__FILE__), 'action_tracker_model.rb')
module ActionTracker
module ControllerMethods
def self.included(base)
base.send :user_stamp, ActionTracker::Record
base.send :extend, ClassMethods
end
module ClassMethods
def track_actions_after(verb, options = {}, &block)
track_actions_by_time(verb, :after, options, &block)
end
def track_actions_before(verb, options = {}, &block)
track_actions_by_time(verb, :before, options, &block)
end
def track_actions(verb, options = {}, &block)
track_actions_by_time(verb, ActionTrackerConfig.default_filter_time, options, &block)
end
def track_actions_by_time(verb, time, options = {}, &block)
keep_params = options.delete(:keep_params) || options.delete('keep_params') || :all
send("#{time}_filter", options) do |x|
x.save_action_for_verb(verb.to_s, keep_params)
block.call(x) unless block.nil?
end
send :include, InstanceMethods
end
end
module InstanceMethods
def save_action_for_verb(verb, keep_params = :all)
if keep_params.is_a? Array
stored_params = params.reject { |key, value| !keep_params.include?(key.to_sym) and !keep_params.include?(key.to_s) }
elsif keep_params.to_s == 'none'
stored_params = {}
elsif keep_params.to_s == 'all'
stored_params = params
end
user = send ActionTrackerConfig.current_user_method
tracked_action = case ActionTrackerConfig.verb_type(verb)
when :groupable
Record.add_or_create :verb => verb, :user => user, :params => stored_params
when :updatable
Record.update_or_create :verb => verb, :user => user, :params => stored_params
when :single
Record.new :verb => verb, :user => user, :params => stored_params
end
user.tracked_actions << tracked_action
end
end
end
module ModelMethods
def self.included(base)
base.send :extend, ClassMethods
end
module ClassMethods
def track_actions(verb, callback, options = {}, &block)
keep_params = options.delete(:keep_params) || options.delete('keep_params') || :all
post_proc = options.delete(:post_processing) || options.delete('post_processing') || Proc.new{}
custom_user = options.delete(:custom_user) || options.delete('custom_user') || nil
custom_target = options.delete(:custom_target) || options.delete('custom_target') || nil
send(callback, Proc.new { |tracked| tracked.save_action_for_verb(verb.to_s, keep_params, post_proc, custom_user, custom_target) }, options)
send :include, InstanceMethods
end
def acts_as_trackable(options = {})
has_many :tracked_actions, { :class_name => "ActionTracker::Record", :order => "updated_at DESC", :foreign_key => :user_id, :dependent => :destroy }.merge(options)
send :include, InstanceMethods
end
end
module InstanceMethods
def time_spent_doing(verb, conditions = {})
time = 0
tracked_actions.all(:conditions => conditions.merge({ :verb => verb.to_s })).each do |t|
time += t.updated_at - t.created_at
end
time.to_f
end
def save_action_for_verb(verb, keep_params = :all, post_proc = Proc.new{}, custom_user = nil, custom_target = nil)
user = self.send(custom_user) unless custom_user.blank?
user ||= ActionTracker::Record.current_user_from_model
target = self.send(custom_target) unless custom_target.blank?
return nil if user.nil?
if keep_params.is_a? Array
stored_params = {}
keep_params.each do |param|
result = self
param.to_s.split('.').each { |m| result = result.send(m) }
stored_params[param.to_s.gsub(/\./, '_')] = result
end
elsif keep_params.to_s == 'none'
stored_params = {}
elsif keep_params.to_s == 'all'
stored_params = self.attributes
end
tracked_action = case ActionTrackerConfig.verb_type(verb)
when :groupable
Record.add_or_create :verb => verb, :params => stored_params, :user => user, :target => target
when :updatable
Record.update_or_create :verb => verb, :params => stored_params, :user => user, :target => target
when :single
Record.new :verb => verb, :params => stored_params, :user => user
end
tracked_action.target = target || self
user.tracked_actions << tracked_action
post_proc.call tracked_action.reload
end
end
end
module ViewHelper
def describe(ta)
"".tap do |result|
if ta.is_a?(ActionTracker::Record)
result << ta.description.gsub(/\{\{(.*?)\}\}/) { eval $1 }
else
result << ""
end
end
end
end
end
ActionController::Base.send :include, ActionTracker::ControllerMethods
ActiveRecord::Base.send :include, ActionTracker::ModelMethods
ActionView::Base.send :include, ActionTracker::ViewHelper