# Summarizes all stats for all tracked sessions and their actions for a given site in a given month. class TrackableStat # Mongoid Config ============================================================================= include Mongoid::Document include Mongoid::Timestamps references_many :trackable_sessions field :site field :bounces, :type => Integer, :default => 0 field :clickthroughs, :type => Integer, :default => 0 field :conversions, :type => Integer, :default => 0 field :duration, :type => Integer, :default => 0 field :new_visits, :type => Integer, :default => 0 field :organic_visits, :type => Integer, :default => 0 field :pageviews, :type => Integer, :default => 0 field :ppc_visits, :type => Integer, :default => 0 field :direct_visits, :type => Integer, :default => 0 field :return_visits, :type => Integer, :default => 0 field :search_visits, :type => Integer, :default => 0 field :visits, :type => Integer, :default => 0 index :site, :unique => false # Scopes ========================================================================================= scope :by_site, lambda { |site| { :where => { :site => site } } } scope :by_date, lambda { |date| { :where => { :created_at => { '$gte' => date.beginning_of_month, '$lte' => date.end_of_month } } } } scope :for_date_range, lambda { |start_date,end_date| { :where => { :created_at => { '$gte' => start_date.beginning_of_month, '$lte' => end_date.end_of_month } } } } scope :for_site, lambda { |site| { :where => { :site => site } } } # Class Methods ================================================================================== # Returns the names of all sites that have been tracked, used in report filters. def self.sites TrackableStat.only(:site).map{|s| s.site.to_s.downcase}.uniq end # Instance Methods =============================================================================== # Increments the running tallies of the session- and action-attributes for a given site in a given # month. For example, an action's clickthroughs or conversions, or the kind of session (direct, # natural, paid, search). # # ==== Attributes # # * +:session+ - action as a string: 'click', 'clickthrough', 'conversion', 'mouseover', 'scroll', 'view' # * +:last_action+ - clickthrough destination # * +:previous_action+ - the referring URL # # ==== Examples # # trackable_stat.touch( 'click', 'cnn.com', 'foo.com/cnn' ) def touch(session, last_action, previous_action = nil) if previous_action.nil? # New session self.trackable_sessions << session self.clickthroughs += 1 if last_action && last_action.clickthrough? self.conversions += 1 if last_action && last_action.conversion? self.direct_visits += 1 if session.kind == 'direct' self.new_visits += 1 if session.new_visit self.organic_visits += 1 if session.kind == 'natural' self.pageviews += 1 self.ppc_visits += 1 if session.kind == 'paid' self.return_visits += 1 if ! session.new_visit self.search_visits += 1 if session.kind == 'search' self.visits += 1 self.bounces += 1 # Assume that it's a bounce until a second view is recorded else # Existing session self.clickthroughs += 1 if last_action.clickthrough? self.conversions += 1 if last_action.conversion? self.duration += last_action.created_at - previous_action.created_at self.pageviews += 1 if last_action.view? self.bounces -= 1 if session.trackable_actions.count == 2 end self.save end end