35

que he encontrado varias soluciones para este problema, por ejemplo railstat de este post:sencillo contador de visitas de páginas vistas en los carriles

Page views in Rails

Tengo un montón de artículos y reseñas que me gustaría una hit counter filtrado por direcciones IP únicas. Exactamente como Stackoverflow lo hace para esta publicación. Pero realmente no me importa una solución como railstat cuando Google Analytics ya está haciendo esto por mí e incluye una gran cantidad de código, haciendo un seguimiento de las direcciones IP únicas, etc. Mi pensamiento actual es usar Garb o algún otro Analytics Complemento para extraer las páginas de las estadísticas si son más antiguas que 12 horas para actualizar alguna tabla, pero también necesito una cache_column.

Supongo que puede extraer estadísticas de Analytics para una página en particular y que actualizan sus estadísticas cada 12 horas.

Me pregunto si hay alguna razón por la cual esta sería una mala idea, o si alguien tiene una solución mejor?

Gracias

Respuesta

92

ACTUALIZACIÓN

El código en esta respuesta se utilizó como base para http://github.com/charlotte-ruby/impressionist Pruébelo


Probablemente le tomaría menos tiempo para codificar esto en su aplicación, entonces sería extraer los datos de Analytics utilizando su API. Es muy probable que esta información sea más precisa y no tendría que depender de una dependencia externa ... también tendría las estadísticas en tiempo real en lugar de esperar 12 horas en los datos de Analytics. request.remote_ip funciona bastante bien. Aquí hay una solución que usa polimorfismo. Tenga en cuenta que este código no se ha probado, pero debe estar cerca.

crear un nuevo modelo/migración para almacenar sus páginas vistas (impresiones):

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 

añadir una línea a su modelo de artículo para la asociación y añadir un método para devolver el recuento de impresión:

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 

Crear un before_filter para articles_controller en la acción show:

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 

A continuación, sólo llaman la unique_impression_count en su opinión

<%[email protected]_impression_count %> 

Si está usando esto en un montón de modelos, es posible que desee para que se seque para arriba. Ponga la definición before_filter en application_controller y usar algo dinámico como:

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) 

Y también mover el código en el modelo artículo a un módulo que será incluido en ActiveRecord :: Base. Podría poner el envío incluido en una configuración/inicializador ... o si quiere volverse loco, simplemente conviértalo todo en un motor de rieles, para poder reutilizarlo en otras aplicaciones.

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

creé un plugin para esto: https://github.com/charlotte-ruby/impressionist – johnmcaliley

+1

He intentado su plugin y funciona como un encanto. Gracias por compartir ! – dgilperez

+0

@cowboycoded ¿Se puede agregar soporte mongoid para este complemento por favor? – hyperrjas

Cuestiones relacionadas