Eine der ersten Anforderungen von Kunden an eine Webseite ist: Wie viele Besucher tummeln sich auf meiner Seite? Dazu baut man einen sogenannten Zugriffszähler (oder auch counter) in seine Applikation ein. In meinen Anfängen schon oft mit PHP gemacht, nie aber mit Rails. Das soll dieser Artikel ändern. Er ist aber auch eine (Gedanken-)Stütze für mich, wenn ich mal wieder drüber nachdenke, wie man einen solchen Counter schreibt oder erweitern kann.
Eigentlich ist es recht einfach, einen Counter in Rails zu erstellen. Wir erzeugen zuerst ein Model ‚visit‘, welches einen Besuch eines Nutzers darstellt.
script/generate model visit |
Dann schreiben wir noch die migrations um und migrieren unsere Datenbank auf die neueste Version.
class CreateVisits < ActiveRecord::Migration def self.up create_table :visits do |t| t.string :ip t.string :referrer t.string :browser_agent t.string :page t.timestamps end end def self.down drop_table :visits end end |
rake db:migrate |
Dann brauchen wir noch eine Methode, in der wir neue User in die DB packen. Ich habe das ganze über eine Methode in meinem PagesController (der meine Seiten verwaltet) gelöst. Diese Methode wird in einem before_filter aufgerufen.
class PagesController < ApplicationController before_filter :write_statistics # ... andere Logik protected def write_statistics # Suche nach Einträgen von heute mit passender IP und Browser Agent visit = Visit.find(:first, :conditions =>{ :ip => request.remote_ip.to_s, :browser_agent => request.env['HTTP_USER_AGENT'], :updated_at => DateTime.now.beginning_of_day..DateTime.now.end_of_day }) if visit.nil? # eintrag existiert noch nicht -> anlegen, fertig v = Visit.new({ :ip => request.remote_ip.to_s, :browser_agent => request.env['HTTP_USER_AGENT'], :page => "#{params[:controller]}/#{params[:action]}", :referrer => request.env['HTTP_REFERRER'] }) # Logging logger.error "Fehler beim Speichern eines Visits" unless v.save end end end |
Den Inhalt der Methode kann man natürlich nach seinen Wünschen anpassen. In dem Fall wird jeder Besucher pro Tag einmal gespeichert. (Hinweis: Evtl. müssen die Parameter config.time_zone und config.active_record.default_timezone in der environment.rb auf die gewünschte Zeitzone angepasst werden)
Ergänzend dazu kann man nun einige Helper erstellen, die überall verwendet werden können:
module PagesHelper def visitors_today v = Visit.find(:all, :conditions => { :updated_at => DateTime.now.beginning_of_day..DateTime.now.end_of_day }) v.size end # day as DateTime def visitors_on day v = Visit.find(:all, :conditions => { :updated_at => day.beginning_of_day..day.end_of_day }) v.size end def visitors_total Visit.count end end |
Erweiterungsmöglichkeiten:
- Alle Seiten speichern, die der Besucher aufruft, Vorteil: bessere Auswertungsmöglichkeiten (Welche Seiten werden häufig besucht, etc.), Nachteil: sehr schnell viele Daten – abhängig von Seitenzahl
- Weitere Kontrollen einbauen: Cookies, Sessions, etc.
- Helpermethoden in einem Partial zu einer „Statistik-Box“ zusammenfassen
- …