35

ho trovato diverse soluzioni per questo problema, per esempio railstat da questo post:semplice contatore di visite per pagine viste in rotaie

Page views in Rails

Ho un sacco di articoli e recensioni che vorrei un hit counter filtrato da IP univoci. Esattamente come Stackoverflow fa per questo post. Ma non mi interessa davvero una soluzione come railstat quando google analytics sta già facendo questo per me e include un sacco di codice, tiene traccia degli IP unici, ecc. Il mio pensiero attuale è usare Garb o altri Analytics plugin per tirare le statistiche delle pagine se sono più vecchie di 12 ore aggiornando qualche tabella, ma ho anche bisogno di una cache_column.

Immagino sia possibile estrarre statistiche da Analytics per una determinata pagina e aggiornare le proprie statistiche ogni 12 ore?

Mi chiedo se ci sono motivi per cui questa sarebbe una cattiva idea, o se qualcuno ha una soluzione migliore?

Grazie

risposta

92

UPDATE

Il codice in questa risposta è stata utilizzata come base per http://github.com/charlotte-ruby/impressionist Provalo


Sarebbe probabilmente si impiega meno tempo per codificare questo in la tua app quindi vorrebbe estrarre i dati da Analytics usando la loro API. Questi dati sarebbero molto probabilmente più accurati e non dovresti affidarti a una dipendenza esterna. Avresti anche le statistiche in tempo reale invece di aspettare 12 ore sui dati di Analytics. request.remote_ip funziona abbastanza bene. Ecco una soluzione che utilizza il polimorfismo. Si prega di notare che questo codice non è stato testato, ma dovrebbe essere vicino.

creare un nuovo modello/migrazione per memorizzare le pagine visualizzate (impressioni):

class Impressions < ActiveRecord::Base 
    belongs_to :impressionable, :polymorphic=>true 
end 

class CreateImpressionsTable < ActiveRecord::Migration 
    def self.up 
    create_table :impressions, :force => true do |t| 
     t.string :impressionable_type 
     t.integer :impressionable_id 
     t.integer :user_id 
     t.string :ip_address 
     t.timestamps 
    end 
    end 

    def self.down 
    drop_table :impressions 
    end 
end 

aggiungere una riga al vostro articolo modello per l'associazione e aggiungere un metodo per restituire contare l'impressione:

class Article < ActiveRecord::Base 
    has_many :impressions, :as=>:impressionable 

    def impression_count 
    impressions.size 
    end 

    def unique_impression_count 
    # impressions.group(:ip_address).size gives => {'127.0.0.1'=>9, '0.0.0.0'=>1} 
    # so getting keys from the hash and calculating the number of keys 
    impressions.group(:ip_address).size.keys.length #TESTED 
    end 
end 

Creare un before_filter per articles_controller sull'azione spettacolo:

before_filter :log_impression, :only=> [:show] 

def log_impression 
    @article = Article.find(params[:id]) 
    # this assumes you have a current_user method in your authentication system 
    @article.impressions.create(ip_address: request.remote_ip,user_id:current_user.id) 
end 

Poi basta chiamare l'unique_impression_count nella vista

<%[email protected]_impression_count %> 

Se si utilizza questo su un gruppo di modelli, si consiglia di asciugare. Mettere il DEF before_filter in application_controller e utilizzare qualcosa di dinamico come:

impressionable_class = controller_name.gsub("Controller","").constantize 
impressionable_instance = impressionable_class.find(params[:id]) 
impressionable_instance.impressions.create(ip_address:request.remote_ip,user_id:current_user.id) 

E anche spostare il codice nel modello articolo a un modulo che sarà incluso in ActiveRecord :: Base. Puoi inserire l'inclusione dell'invio in un config/inizializzatore .. o se vuoi diventare pazzo, trasforma l'intero processo in un motore di rotaie, in modo da poterlo riutilizzare su altre app.

module Impressionable 
    def is_impressionable 
    has_many :impressions, :as=>:impressionable 
    include InstanceMethods 
    end 
    module InstanceMethods 
    def impression_count 
     impressions.size 
    end 

    def unique_impression_count 
     impressions.group(:ip_address).size 
    end 
    end 
end 

ActiveRecord::Base.extend Impressionable 
+22

ho creato un plugin per questo: https://github.com/charlotte-ruby/impressionist – johnmcaliley

+1

Ho provato i plugin e funziona come un fascino. Grazie per la condivisione ! – dgilperez

+0

@cowboycoded Puoi aggiungere supporto mongoid per questo plugin per favore? – hyperrjas

Problemi correlati