GithubHelp home page GithubHelp logo

charlotte-ruby / impressionist Goto Github PK

View Code? Open in Web Editor NEW
1.5K 32.0 313.0 749 KB

Rails Plugin that tracks impressions and page views

License: MIT License

Ruby 94.77% JavaScript 0.47% CSS 0.41% HTML 4.35%
impression unique-impressions logging-impressions counts-impressions ruby impressions-table

impressionist's Introduction

Impressionist Logo

Main Code Climate

WE ARE LOOKING FOR MAINTAINERS. CONTACT @johnmcaliley IF YOU ARE INTERESTED IN HELPING

impressionist

A lightweight plugin that logs impressions per action or manually per model


What does this thing do?

Logs an impression... and I use that term loosely. It can log page impressions (technically action impressions), but it is not limited to that. You can log impressions multiple times per request. And you can also attach it to a model. The goal of this project is to provide customizable stats that are immediately accessible in your application as opposed to using Google Analytics and pulling data using their API. You can attach custom messages to impressions. No reporting yet.. this thingy just creates the data.

What about bots?

They are ignored. 1200 known bots have been added to the ignore list as of February 1, 2011. Impressionist uses this list: http://www.user-agents.org/allagents.xml

Installation

Add it to your Gemfile

#rails 6
gem 'impressionist'

#rails 5 or lower
gem 'impressionist', '~>1.6.1'

Install with Bundler

bundle install

Generate the impressions table migration

rails g impressionist

Run the migration

rake db:migrate

The following fields are provided in the migration:

t.string   "impressionable_type"  # model type: Widget
t.integer  "impressionable_id"    # model instance ID: @widget.id
t.integer  "user_id"              # automatically logs @current_user.id
t.string   "controller_name"      # logs the controller name
t.string   "action_name"          # logs the action_name
t.string   "view_name"            # TODO: log individual views (as well as partials and nested partials)
t.string   "request_hash"         # unique ID per request, in case you want to log multiple impressions and group them
t.string   "session_hash"         # logs the rails session
t.string   "ip_address"           # request.remote_ip
t.text     "params"               # request.params, except action name, controller name and resource id
t.string   "referrer"             # request.referer
t.string   "message"              # custom message you can add
t.datetime "created_at"           # I am not sure what this is.... Any clue?
t.datetime "updated_at"           # never seen this one before either....  Your guess is as good as mine?? ;-)

Usage

  1. Log all actions in a controller

     WidgetsController < ApplicationController
       impressionist
     end
    
  2. Specify actions you want logged in a controller

     WidgetsController < ApplicationController
       impressionist :actions=>[:show,:index]
     end
    
  3. Make your models impressionable. This allows you to attach impressions to an AR model instance. Impressionist will automatically log the Model name (based on action_name) and the id (based on params[:id]), but in order to get the count of impressions (example: @widget.impression_count), you will need to make your model impressionable

     class Widget < ActiveRecord::Base
       is_impressionable
     end
    
  4. Log an impression per model instance in your controller. Note that it is not necessary to specify "impressionist" (usage #1) in the top of you controller if you are using this method. If you add "impressionist" to the top of your controller and also use this method in your action, it will result in 2 impressions being logged (but associated with one request_hash). If you're using friendly_id be sure to log impressionist this way, as params[:id] will return a string(url slug) while impressionable_id is a Integer column in database. Also note that you have to take step #3 for the Widget model for this to work.

     def show
       @widget = Widget.find
       impressionist(@widget, "message...") # 2nd argument is optional
     end
    
  5. Get unique impression count from a model. This groups impressions by request_hash, so if you logged multiple impressions per request, it will only count them one time. This unique impression count will not filter out unique users, only unique requests

     @widget.impressionist_count
     @widget.impressionist_count(:start_date=>"2011-01-01",:end_date=>"2011-01-05")
     @widget.impressionist_count(:start_date=>"2011-01-01")  #specify start date only, end date = now
    
  6. Get the unique impression count from a model filtered by IP address. This in turn will give you impressions with unique request_hash, since rows with the same request_hash will have the same IP address.

     @widget.impressionist_count(:filter=>:ip_address)
    
  7. Get the unique impression count from a model filtered by params. This in turn will give you impressions with unique params.

     @widget.impressionist_count(:filter => :params)
    
  8. Get the unique impression count from a model filtered by session hash. Same as #6 regarding request hash. This may be more desirable than filtering by IP address depending on your situation, since filtering by IP may ignore visitors that use the same IP. The downside to this filtering is that a user could clear session data in their browser and skew the results.

     @widget.impressionist_count(:filter=>:session_hash)
    
  9. Get total impression count. This may return more than 1 impression per http request, depending on how you are logging impressions

     @widget.impressionist_count(:filter=>:all)
    
  10. Get impression count by message. This only counts impressions of the given message.

    @widget.impressionist_count(:message=>"pageview", :filter=>:all)
    

Logging impressions for authenticated users happens automatically. If you have a current_user helper or use @current_user in your before_filter (or before_action in Rails >= 5.0) to set your authenticated user, current_user.id will be written to the user_id field in the impressions table.

Adding a counter cache

Impressionist makes it easy to add a counter_cache column to your model. The most basic configuration looks like:

is_impressionable :counter_cache => true

This will automatically increment the impressions_count column in the included model. Note: You'll need to add that column to your model. If you'd like specific a different column name, you can:

is_impressionable :counter_cache => true, :column_name => :my_column_name

If you'd like to include only unique impressions in your count:

# default will be filtered by ip_address
is_impressionable :counter_cache => true, :column_name => :my_column_name, :unique => true

If you'd like to specify what sort of unique impression you'd like to save? Fear not, Any option you pass to unique, impressionist_count will use it as its filter to update_counters based on that unique option.

# options are any column in the impressions' table.
is_impressionable :counter_cache => true, :column_name => :my_column_name, :unique => :request_hash
is_impressionable :counter_cache => true, :column_name => :my_column_name, :unique => :all

Adding column to model

It is as simple as this:

t.integer :my_column_name, :default => 0

If you want to use the typical Rails 4 migration generator, you can:

rails g migration AddImpressionsCountToBook impressions_count:int

What if I only want to record unique impressions?

Maybe you only care about unique impressions and would like to avoid unnecessary database records. You can specify conditions for recording impressions in your controller:

# only record impression if the request has a unique combination of type, id, and session
impressionist :unique => [:impressionable_type, :impressionable_id, :session_hash]

# only record impression if the request has a unique combination of controller, action, and session
impressionist :unique => [:controller_name, :action_name, :session_hash]

# only record impression if session is unique
impressionist :unique => [:session_hash]

# only record impression if param is unique
impressionist :unique => [:params]

Or you can use the impressionist method directly:

impressionist(impressionable, "some message", :unique => [:session_hash])

Are you using Mongoid?

Execute this command on your terminal/console:

rails g impressionist --orm mongoid

This command create a file impression.rb on config/initializer folder. Add config.orm = :mongoid to this file:

# Use this hook to configure impressionist parameters
Impressionist.setup do |config|
  # Define ORM. Could be :active_record (default), :mongo_mapper or :mongoid
  # config.orm = :active_record
  config.orm = :mongoid
end

Contributing to impressionist

  • Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
  • Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
  • Fork the project
  • Start a feature/bugfix branch
  • Commit and push until you are happy with your contribution
  • Make sure to add rpsec tests for it. Patches or features without tests will be ignored. Also, try to write better tests than I do ;-)
  • If adding engine controller or view functionality, use HAML and Inherited Resources.
  • All testing is done inside a small Rails app (test_app). You will find specs within this app.

Want to run the tests? Ok mummy

  • bundle install
  • rails g impressionist
  • rake db:migrate && rake db:test:prepare
  • Run rake or rspec spec inside test_app dir
  • nothing else.
  • :wq

Contributors

WE ARE CURRENTLY LOOKING FOR SOMEONE TO HELP MAINTAIN THIS REPOSITORY. IF YOU ARE INTERESTED, MESSAGE @johnmcaliley.

Copyright (c) 2011 John McAliley. See LICENSE.txt for further details.

impressionist's People

Contributors

acnalesso avatar adamferguson avatar asharma-ror avatar beghbali avatar blarralde avatar charlotte-ruby-bot avatar coryschires avatar geoffharcourt avatar georgmittendorfer avatar hyperrjas avatar invalidusrname avatar jgrau avatar jgwmaxwell avatar johnmcaliley avatar joofsh avatar josephmg avatar kinopyo avatar linuus avatar msimonborg avatar nirdshabo avatar petergoldstein avatar rossta avatar rposborne avatar sferik avatar tansengming avatar tauhidul35 avatar tute avatar tyrauber avatar xiaohui-zhangxh avatar yskkin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

impressionist's Issues

associations are not working on fetching object

here are my models:

class A < ActiveRecord::Base
is_impressionable :counter_cache => true
has_many :comments
end

class B < ActiveRecord::Base
is_impressionable :counter_cache => true
belongs_to A
end

now it wont work:
b = B.first
b.a.comments shows undefined method comments for A.
but b.a works fine.

if is_impressionable class method is been called after all association declaration then it works fine.

class B < ActiveRecord::Base

belongs_to A
is_impressionable :counter_cache => true

end

then all will work fine

NB: I am using rails 3.2.2 with impressionist 1.1.1

Methods not added to model?

I may be missing something, but it seems like the latest updates where loading has been moved to the ORM has resulted in all of the important impressionist methods not being added to the model. None of the methods are attached to the model and trying to run on the latest version gives a '[Model] is not impressionable!' error for everything.

Filter does not work with mongoid

I'm using Rails 3.2.8 with Mongoid.

I tried to use :filter => :session_hash but it didn't work.

everytime I hit F5, the count increment in the view.

when I look at query in logs, i get this

database=mydb_development command={:count=>"impressions", :query=> {"impressionable_id"=>"50a720712b225bd8e2000001", "impressionable_type"=>"Mymodel", "impressionable_field"=>{"$in"=>[:impressions, nil]}, "session_hash"=>{"$ne"=>nil}}} (1.6191ms)

data insertion have done just fine, and I could get request.session_options[:id].

Non integer ids

I'm having an issue with URLs that uses strings as their ID, like:

blabla.com/users/dude

Looking at this line, I found that it stores params[:id] directly inside impressionable_id column which results in my case storing NULL inside the table since impressionable_id column is supposed to be integer. One way to solve this is change the column type to string.

I tried something like:
impressionist(@user) #show action

but it didn't store the controller and the action names.

Update to 1.3 causes uninitialized constant errors

uninitialized constant 
... yadda yadda...
# /home/aaron/.rvm/gems/ruby-1.9.3-p392@mhmr/gems/impressionist-1.3.0/lib/impressionist/models/active_record/impression.rb:14:in `update_impressions_counter_cache'

1.2 works fine, i suspect that this was caused by df84891

undefined method `[]' for nil:NilClass when viewing duplicated objects

Looks like we blow up trying retrieved cached items when viewing a duplicated impressionist object.

C:/Ruby192/lib/ruby/gems/1.9.1/bundler/gems/impressionist-8f2c219b97d0/lib/impressionist/models/mongoid/impressionist/impressionable.rb:45:in update_impressionist_counter_cache' activesupport (3.2.11) lib/active_support/core_ext/object/try.rb:36:intry'
C:/Ruby192/lib/ruby/gems/1.9.1/bundler/gems/impressionist-8f2c219b97d0/lib/impressionist/models/mongoid/impression.rb:27:in block in <class:Impression>' activesupport (3.2.11) lib/active_support/callbacks.rb:416:in_run__327048654__create__148435328__callbacks'
activesupport (3.2.11) lib/active_support/callbacks.rb:405:in __run_callback' activesupport (3.2.11) lib/active_support/callbacks.rb:385:in_run_create_callbacks'
activesupport (3.2.11) lib/active_support/callbacks.rb:81:in run_callbacks' mongoid (2.4.3) lib/mongoid/callbacks.rb:43:inblock in run_callbacks'
mongoid (2.4.3) lib/mongoid/callbacks.rb:68:in call' mongoid (2.4.3) lib/mongoid/callbacks.rb:68:inrun_cascading_callbacks'
mongoid (2.4.3) lib/mongoid/callbacks.rb:42:in run_callbacks' mongoid (2.4.3) lib/mongoid/persistence/insertion.rb:25:inblock (2 levels) in prepare'
activesupport (3.2.11) lib/active_support/callbacks.rb:414:in _run__327048654__save__148435328__callbacks' activesupport (3.2.11) lib/active_support/callbacks.rb:405:in__run_callback'
activesupport (3.2.11) lib/active_support/callbacks.rb:385:in _run_save_callbacks' activesupport (3.2.11) lib/active_support/callbacks.rb:81:inrun_callbacks'
mongoid (2.4.3) lib/mongoid/callbacks.rb:43:in block in run_callbacks' mongoid (2.4.3) lib/mongoid/callbacks.rb:68:incall'
mongoid (2.4.3) lib/mongoid/callbacks.rb:68:in run_cascading_callbacks' mongoid (2.4.3) lib/mongoid/callbacks.rb:42:inrun_callbacks'
mongoid (2.4.3) lib/mongoid/persistence/insertion.rb:24:in block in prepare' mongoid (2.4.3) lib/mongoid/persistence/insertion.rb:22:intap'
mongoid (2.4.3) lib/mongoid/persistence/insertion.rb:22:in prepare' mongoid (2.4.3) lib/mongoid/persistence/operations/insert.rb:26:inpersist'
mongoid (2.4.3) lib/mongoid/persistence.rb:49:in insert' mongoid (2.4.3) lib/mongoid/persistence.rb:154:inupsert'
mongoid (2.4.3) lib/mongoid/persistence.rb:177:in block (2 levels) in create' mongoid (2.4.3) lib/mongoid/persistence.rb:177:intap'
mongoid (2.4.3) lib/mongoid/persistence.rb:177:in block in create' mongoid (2.4.3) lib/mongoid/threaded/lifecycle.rb:173:in_creating'
mongoid (2.4.3) lib/mongoid/persistence.rb:176:in create' C:/Ruby192/lib/ruby/gems/1.9.1/bundler/gems/impressionist-8f2c219b97d0/app/controllers/impressionist_controller.rb:36:inimpressionist_subapp_filter'
C:/Ruby192/lib/ruby/gems/1.9.1/bundler/gems/impressionist-8f2c219b97d0/app/controllers/impressionist_controller.rb:6:in block in impressionist' activesupport (3.2.11) lib/active_support/callbacks.rb:539:in_run__711426409__process_action__1032293139__callbacks'
activesupport (3.2.11) lib/active_support/callbacks.rb:405:in __run_callback' activesupport (3.2.11) lib/active_support/callbacks.rb:385:in_run_process_action_callbacks'
activesupport (3.2.11) lib/active_support/callbacks.rb:81:in run_callbacks' actionpack (3.2.11) lib/abstract_controller/callbacks.rb:17:inprocess_action'
actionpack (3.2.11) lib/action_controller/metal/rescue.rb:29:in process_action' actionpack (3.2.11) lib/action_controller/metal/instrumentation.rb:30:inblock in process_action'
activesupport (3.2.11) lib/active_support/notifications.rb:123:in block in instrument' activesupport (3.2.11) lib/active_support/notifications/instrumenter.rb:20:ininstrument'
activesupport (3.2.11) lib/active_support/notifications.rb:123:in instrument' actionpack (3.2.11) lib/action_controller/metal/instrumentation.rb:29:inprocess_action'
actionpack (3.2.11) lib/action_controller/metal/params_wrapper.rb:207:in process_action' newrelic_rpm (3.5.8.72) lib/new_relic/agent/instrumentation/rails3/action_controller.rb:34:inblock in process_action'
newrelic_rpm (3.5.8.72) lib/new_relic/agent/instrumentation/controller_instrumentation.rb:268:in block in perform_action_with_newrelic_trace' newrelic_rpm (3.5.8.72) lib/new_relic/agent/method_tracer.rb:240:intrace_execution_scoped'
newrelic_rpm (3.5.8.72) lib/new_relic/agent/instrumentation/controller_instrumentation.rb:263:in perform_action_with_newrelic_trace' newrelic_rpm (3.5.8.72) lib/new_relic/agent/instrumentation/rails3/action_controller.rb:33:inprocess_action'
actionpack (3.2.11) lib/abstract_controller/base.rb:121:in process' actionpack (3.2.11) lib/abstract_controller/rendering.rb:45:inprocess'
actionpack (3.2.11) lib/action_controller/metal.rb:203:in dispatch' actionpack (3.2.11) lib/action_controller/metal/rack_delegation.rb:14:indispatch'
actionpack (3.2.11) lib/action_controller/metal.rb:246:in block in action' actionpack (3.2.11) lib/action_dispatch/routing/route_set.rb:73:incall'
actionpack (3.2.11) lib/action_dispatch/routing/route_set.rb:73:in dispatch' actionpack (3.2.11) lib/action_dispatch/routing/route_set.rb:36:incall'
journey (1.0.4) lib/journey/router.rb:68:in block in call' journey (1.0.4) lib/journey/router.rb:56:ineach'
journey (1.0.4) lib/journey/router.rb:56:in call' actionpack (3.2.11) lib/action_dispatch/routing/route_set.rb:601:incall'
omniauth (1.1.3) lib/omniauth/strategy.rb:177:in call!' omniauth (1.1.3) lib/omniauth/strategy.rb:157:incall'
omniauth (1.1.3) lib/omniauth/strategy.rb:177:in call!' omniauth (1.1.3) lib/omniauth/strategy.rb:157:incall'
omniauth (1.1.3) lib/omniauth/strategy.rb:177:in call!' omniauth (1.1.3) lib/omniauth/strategy.rb:157:incall'
omniauth (1.1.3) lib/omniauth/strategy.rb:177:in call!' omniauth (1.1.3) lib/omniauth/strategy.rb:157:incall'
omniauth (1.1.3) lib/omniauth/strategy.rb:177:in call!' omniauth (1.1.3) lib/omniauth/strategy.rb:157:incall'
omniauth (1.1.3) lib/omniauth/builder.rb:48:in call' mongoid (2.4.3) lib/rack/mongoid/middleware/identity_map.rb:33:inblock in call'
mongoid (2.4.3) lib/mongoid.rb:132:in unit_of_work' mongoid (2.4.3) lib/rack/mongoid/middleware/identity_map.rb:33:incall'
newrelic_rpm (3.5.8.72) lib/new_relic/rack/error_collector.rb:8:in call' newrelic_rpm (3.5.8.72) lib/new_relic/rack/agent_hooks.rb:14:incall'
newrelic_rpm (3.5.8.72) lib/new_relic/rack/browser_monitoring.rb:12:in call' actionpack (3.2.11) lib/action_dispatch/middleware/best_standards_support.rb:17:incall'
rack (1.4.5) lib/rack/etag.rb:23:in call' rack (1.4.5) lib/rack/conditionalget.rb:25:incall'
actionpack (3.2.11) lib/action_dispatch/middleware/head.rb:14:in call' actionpack (3.2.11) lib/action_dispatch/middleware/params_parser.rb:21:incall'
actionpack (3.2.11) lib/action_dispatch/middleware/flash.rb:242:in call' rack (1.4.5) lib/rack/session/abstract/id.rb:210:incontext'
rack (1.4.5) lib/rack/session/abstract/id.rb:205:in call' actionpack (3.2.11) lib/action_dispatch/middleware/cookies.rb:341:incall'
actionpack (3.2.11) lib/action_dispatch/middleware/callbacks.rb:28:in block in call' activesupport (3.2.11) lib/active_support/callbacks.rb:405:in_run__464494528__call__148435328__callbacks'
activesupport (3.2.11) lib/active_support/callbacks.rb:405:in __run_callback' activesupport (3.2.11) lib/active_support/callbacks.rb:385:in_run_call_callbacks'
activesupport (3.2.11) lib/active_support/callbacks.rb:81:in run_callbacks' actionpack (3.2.11) lib/action_dispatch/middleware/callbacks.rb:27:incall'
actionpack (3.2.11) lib/action_dispatch/middleware/reloader.rb:65:in call' actionpack (3.2.11) lib/action_dispatch/middleware/remote_ip.rb:31:incall'
actionpack (3.2.11) lib/action_dispatch/middleware/debug_exceptions.rb:16:in call' actionpack (3.2.11) lib/action_dispatch/middleware/show_exceptions.rb:56:incall'
railties (3.2.11) lib/rails/rack/logger.rb:32:in call_app' railties (3.2.11) lib/rails/rack/logger.rb:16:inblock in call'
activesupport (3.2.11) lib/active_support/tagged_logging.rb:22:in tagged' railties (3.2.11) lib/rails/rack/logger.rb:16:incall'
actionpack (3.2.11) lib/action_dispatch/middleware/request_id.rb:22:in call' rack (1.4.5) lib/rack/methodoverride.rb:21:incall'
rack (1.4.5) lib/rack/runtime.rb:17:in call' activesupport (3.2.11) lib/active_support/cache/strategy/local_cache.rb:72:incall'
rack (1.4.5) lib/rack/lock.rb:15:in call' actionpack (3.2.11) lib/action_dispatch/middleware/static.rb:62:incall'
railties (3.2.11) lib/rails/engine.rb:479:in call' railties (3.2.11) lib/rails/application.rb:223:incall'
railties (3.2.11) lib/rails/railtie/configurable.rb:30:in method_missing' rack (1.4.5) lib/rack/deflater.rb:13:incall'
rack (1.4.5) lib/rack/content_length.rb:14:in call' railties (3.2.11) lib/rails/rack/log_tailer.rb:17:incall'
thin (1.5.0) lib/thin/connection.rb:81:in block in pre_process' thin (1.5.0) lib/thin/connection.rb:79:incatch'
thin (1.5.0) lib/thin/connection.rb:79:in pre_process' thin (1.5.0) lib/thin/connection.rb:54:inprocess'
thin (1.5.0) lib/thin/connection.rb:39:in receive_data' eventmachine-1.0.1-x86 (mingw32) lib/eventmachine.rb:187:inrun_machine'
eventmachine-1.0.1-x86 (mingw32) lib/eventmachine.rb:187:in run' thin (1.5.0) lib/thin/backends/base.rb:63:instart'
thin (1.5.0) lib/thin/server.rb:159:in start' rack (1.4.5) lib/rack/handler/thin.rb:13:inrun'
rack (1.4.5) lib/rack/server.rb:268:in start' railties (3.2.11) lib/rails/commands/server.rb:70:instart'
railties (3.2.11) lib/rails/commands.rb:55:in block in <top (required)>' railties (3.2.11) lib/rails/commands.rb:50:intap'
railties (3.2.11) lib/rails/commands.rb:50:in <top (required)>' script/rails:6:inrequire'
script/rails:6:in `

'

Compatible with Mongoid

Hello is this gem compatible with Mongoid?

I have try install this gem with mongoid but not works for me :(

Thank you!

Impressioning a model from a View

¿Is this possible at all?

My use case consists of tracking impressions from banners, that are not served from a controller but from a view helper. I could consider using a rails cell if this is possible.

Thanks!

And also thanks for the great work.

undefined method `impressions_count'

Controller

def show
@widget = Widget.first
impressionist(@widget,message:"wtf is a first widget?")
end

Model

is_impressionable :counter_cache => true

Error

NoMethodError (undefined method `impressions_count' for #Widget:0x007fc7c0fa8e78):

Any clue?

Possible to get impression data directly?

Hi. I'm enjoying my time with Impressionist so far. With Devise I overrode the Devise::SessionsController to get login impressions (logout, failed passwords, whatever) It works great.

class DemoSessionController < Devise::SessionsController
  def create
    if not @current_member.nil?
      impressionist(@current_member, :unique => [:session_hash])
    end
    super
  end
end

However I'm trying to get the impression data itself. I want to get all impressions for all logins/users for a date range (1 week) and group them by impressions.created_at date with a custom function to determine if the created_at date is within a daily range. e.g. I want to chart the login counts for each day in the last week, maybe even by specific user_id.

I can go and write some queries of my own (there's no Impressions Model) to retrieve this, but I thought I would ask if there was a secret method to get the impression data itself. The impressionist_count method is limited to only returning the size of impressions based on the set criteria.

Thanks.

Linking impressions of sessions to each other

What do you think about adding some methods that let you easily "travel the users path" with something like imp.next and imp.previous?
Could be useful to analyze user behavior etc.
I think I could provide a PR given you like the idea.

undefined method `gsub!' for #<Arel::InsertManager>

Hi !

I'm getting this error using impressionist in my Rails3.1 application, using mysql. I have a Service model which is_impressionable and a impressionist :actions => [:show] in my ServicesController. The error appears only when I add the impressionist line to the controller.

The error is not very descriptive, just a

NoMethodError in ServicesController#show

undefined method `gsub!' for #<Arel::InsertManager:0x0000012a7ac170>

Any ideas will be appreciated!

README includes incorrect sample code

impressionist(@widget,message:"wtf is a widget?") #message is optional

should be:

impressionist(@widget, :message => "wtf is a widget?") #message is optional

[Suggestion] Create built-in parser for user-agent info

Hi,

I'm currently using latest version of impressionist in my project to register views and I'm also using it to save user-agent data from users.

In one of my controller, I use the following method:

impressionist(@tracker, request.env['HTTP_USER_AGENT']) 

Impressionist saves the User Agent info into message variable.

Two example of the user agent info saved in the variables are:

  1. Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.163 Safari/535.19
  2. Mozilla/5.0 (iPhone; CPU iPhone OS 5_0_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A405 Safari/7534.48.3

The issue with it is that it's hard to parse such information. There are thousand of user agent info and it would be great if there's a way to categorize them automatically by Impressionist.

This would make Impressionist much more powerful ruby gem and eventually, it would also parse the IP address by country.

Invalid migration generated

According to the documentation on the main page, the table migration generated should look like

t.string   "impressionable_type"
t.integer  "impressionable_id"
t.integer  "user_id"
t.string   "controller_name"
t.string   "action_name"
t.string   "view_name"nested partials)
t.string   "request_hash"
t.string   "session_hash"
t.string   "ip_address"
t.string   "referrer"
t.string   "message"
t.datetime "created_at"
t.datetime "updated_at"

However, running rails g impressionist produces

t.string :impressionable_type
t.integer :impressionable_id
t.integer :user_id
t.string :controller_name
t.string :action_name
t.string :view_name
t.string :request_hash
t.string :ip_address
t.string :session_hash
t.text :message
t.text :referrer
t.timestamps

Looking at the source it looks like a simple issue with the generator, however it is causing problems. With the migration as this, I am receiving the following error

Mysql2::Error: BLOB/TEXT column 'message' used in key specification without a key length: CREATE  INDEX `impressionable_type_message_index` ON `impressions` (`impressionable_type`, `message`, `impressionable_id`)

According to bundle I'm using version 1.2.0

attr_accessible and mass assignment

attr_accessible is going to be enforced by default in the upcoming version of rails. Right now this gem doesn't work if attr_accesible is nil on the model because of mass assignment being used to create the impression records.

I think the methods that create impressions should use :without_protection => true or some other method that gets around mass assignment to properly account for this.

Counter Cache column options do not accept multiple columns

I would like to cache both, total views and unique views.

The following does not make that happen (for obvious reasons):
is_impressionable :counter_cache => { :column_name => :view_counter_cache }
is_impressionable :counter_cache => { :column_name => :view_counter_cache_unique, :unique => true }

Is there a way to achieve this regardless, or could it be added?

Example:
is_impressionable :counter_cache => [{:column_name => :counter_cache}, {:column_name => :counter_cache_unique, :unique => true}]

or:

is_impressionable :counter_cache => {:counter_cache => {}, :counter_cache_unique => {:unique => true}}

Creating scopes based on impressions

I don't know if this is right for the issues section but I've been trying to scope my model based on impressions (most viewed), i haven't been able to figure a way around, i i wish someone can help me figure this out or probably create a pull request for that.

Impressions table should use text rather than string

You should update the migrations to change the following columns to text rather than string:

request_hash, session_hash, message, referrer

This is actually a really big problem. Specifically the referrer column. When searching from Google, the http referrer is very often over 255 characters which means any page using this gem will throw 500 errors when people try to visit from Google. That's no good. Especially because there's really no way to anticipate the problem until the code is in production.

I don't mind making a pull request, but it's an obvious fix, and I'm not sure how you want to do it (i.e. a new migration or amending the existing one). That said, if a pull request would be helpful, let me know and I'll take care of it.

Postgresql Group By Errors

To get the unique_impression_count and such to work I had to group by every column in the table. Didn't need this for sqlite.

Counter Cache Conditions

It would be useful to be able to specify conditions for the counter cache, so that we could create multiple counter caches, say one for views, one for downloads, one for endorsements, etc.

Example:
is_impressionable :counter_cache => {:unique => true, :conditions => {:action_name => "download"}}

Problem on Rails 3.2.8 with is_impressionable?

I'm having trouble running this on rails 3.2.8 and I'm out of ideas.

.../gems/activerecord-3.2.8/lib/active_record/dynamic_matchers.rb:50:in `method_missing': undefined local variable or method `is_impressionable' for #<Class:0x007fe365fb4f00> (NameError)
/app/models/user.rb:3:in `<class:User>'
/app/models/user.rb:1:in `<top (required)>'

Here is my class:

class User < ActiveRecord::Base
  is_impressionable
end

In a controller:
impressionist :actions=>[:show,:index]

works fine.

What am I missing?

Counter Cache only?

Is it possible to only update the counter_cache field in my model and not write a new record in the impressionist table? even with Unique set to true, the impressionist table in the database could be ginormous!

Impressionist and Resque

I'm having some issues with Resque and Impressionist.

My Model

class Presentation < ActiveRecord::Base
  has_one :video

  is_impressionable

  def create_slides
    Resque.enqueue(ConvertSlides, self.id, pdf.path)
  end

end

My worker fails.

undefined local variable or method is_impressionable' for #<Class:0x00000101f772e8> /Users/joshcrowder/rails/rails3/arcticfox/app/models/presentation.rb:10:inclass:Presentation'

Any ideas why? What do I have todo to get this wroking?

Friendly_id and impressionist 1.0.1 not recording impressionable id

I saw in the other issue (#22) from a couple of months ago where this was working on rails 3.1.2. I have the same setup other than I have Rails 3.1.3, however it doesn't seem to be working for me - impressionist records the id just fine if I go to

.../article/13

but not

..article/title-of-article

I'm using Rails 3.1.3, Friendly_id 4.0.0-beta14 and impressionist 1.0.1

I'm wondering if you have any pointers for me on where to start looking and yes I have restarted the server :)

Pass options only in impressionist method

When using the impressionist method directly:

impressionist(impressionable, "some message", :unique => [:session_hash])

Can I pass something like

impressionist(impressionable, :unique => [:session_hash])

I don't want to pass any message.

Thank you.

Model is not impressionable! in version 1.1.0

def impressionist(obj,message=nil,opts={})
unless bypass
if obj.respond_to?("impressionable?")
if unique_instance?(obj, opts[:unique])
obj.impressions.create(associative_create_statement({:message => message}))
end
else
# we could create an impression anyway. for classes, too. why not?
raise "#{obj.class.to_s} is not impressionable!"
end
end
end

the highlighted code throws the exception.
I have used this in the model

is_impressionable :counter_cache => true

undefined method impressionist_count

I'm getting the following error when I try to call the impressionist count on a model that is_impressionable:

undefined method `impressionist_count' for #ActiveRecord::Relation:0x10489ac10

In my controller I'm called Model.impressionist_count

The impressions are successfully being stored in the impressions table, I just can't view them.

Rails 3.0.7 on Ruby 1.8.7

Mysql2::Error: BLOB/TEXT column 'session_hash' used in key specification without a key length...

Hi, I'm using this awesome plugin, but I've encountered a little problem when doing the migration, the mysql2 gem returns:

Mysql2::Error: BLOB/TEXT column 'session_hash' used in key specification without a key length: CREATE INDEX poly_session_index ON impressions (impressionable_type, impressionable_id, session_hash)

I've found a stackoverflow with an anwser about this error: http://stackoverflow.com/questions/1827063/mysql-error-key-specification-without-a-key-length

I'm already dont know how can I fix this whitout creating other problems when using this plugin. This error was ocurred to anyone else, or just me ?

Thanks in advance.

Ruby 1.9.2p290
Rails 3.1.1
Linux Mint (Ubuntu) 11.10
MySQL2 gem

Impressionist Signs Out Users

I'm using the sessions model outlined in the Ruby on Rails Tutorial. Unfortunately, Impressionist breaks this model when I call it like so:

def show
      @user = User.find(params[:id])
      impressionist(@user)
end

If I view a user profile (thus calling impressionist), I get logged out as soon as I click the next link or press refresh. Any idea what might be causing this?

Allow controllers to be tracked without having a model

At the moment the code takes the name of the Controller and assumes that there's a Model of the same name.

Line 81 of impressionist_controller.rb:
:impressionable_type => controller_name.singularize.camelize,

Line 11 of /lib/impressionist/models/active_record/impression.rb:
impressionable_class = self.impressionable_type.constantize

This will fail if there's a "PostController" but no "Posts" model.

Steps to reproduce:
1/ Delete "Posts" model.
2/ rake spec

Expected behavior:
That the controller saves itself as the type ie. impressionable_type is "self.class.to_s" and impression.rb doesn't try and call constantize a model that doesn't exist.

Counter Cache when using STI throws: You have a nil object when you didn't expect it!

The model uses Single Table Inheritance. If the type column is blank, the issue does not occur.

In model:
is_impressionable :counter_cache => { :column_name => :view_counter_cache }

You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.[]

Backtrace:
impressionist (1.0.1) app/models/impressionist/impressionable.rb:47:in update_counter_cache' activesupport (3.1.3) lib/active_support/core_ext/object/try.rb:32:intry'
impressionist (1.0.1) app/models/impression.rb:13:in update_impressions_counter_cache' activesupport (3.1.3) lib/active_support/callbacks.rb:401:in_run_save_callbacks'
activesupport (3.1.3) lib/active_support/callbacks.rb:81:in run_callbacks' activerecord (3.1.3) lib/active_record/callbacks.rb:264:increate_or_update'
activerecord (3.1.3) lib/active_record/persistence.rb:37:in save' activerecord (3.1.3) lib/active_record/validations.rb:50:insave'
activerecord (3.1.3) lib/active_record/attribute_methods/dirty.rb:22:in `save'

The problem seems to stem from using self.class.counter_cache_options

undefined method `impressions_count=' in Rails 3.1

I'm continuing to have the problem first depicted in Issue # 7.

I've created a column in my impressionable table named impressions_count and declared my model is_impressionable :counter_cache => true. However, this still results in a undefined method `impressions_count=' error.

I think the key difference is that I'm using Rails 3.1. Have you encountered any issues with this? I'm happy to dig into it for a possible pull, but I wanted to make sure it wasn't something that was already on your radar.

Count for specific action

Is there any way of getting the impressionist_count method to return only the count for a specific action?

If it's there, I could not find it. The information is in the database already, though, which would make it a nice and easy addition in my opinion: it's only an issue of deciding for a method signature.

A possibility could be

impressionist_count(:where => { :action_name => 'show' })

This should fit in nicely with the syntax for ActiveRecord's where.

impressions_count cache doesn't work

tried to cache the impressions count here, but didn't work, it stills search for all the impressions in the database

I've added impressions_count (integer) column to all models, and added :counter_cache => true to all models that use is_impressionable, but it still searching for impressions in impressions table

capture unique impressions only?

Is there a way to capture just unique views and not every view? I'm worried about all the excess records in my database since I don't need every impression counted. If we could do something like is_impressionable, :unique_only => true in our model it would be awesome.

Regards,

Jordan

Impressions should be logged after controller actions finish executing

I ran into a RecordNotFound exception as detailed in this SO: http://stackoverflow.com/questions/12148785/rails-find-by-id-raises-exception/12148939#12148939

Essentially if passed a bogus ID impressionist tries to log an impression for an object that doesn't exist. This might just be a problem with my setup, but here's my model setup:

is_impressionable :counter_cache => { :column_name => :views}

Deleting this line from my model allowed my controller action to properly handle the bogus id.

Impressionist Not Compatible with Friendly_ID Gem

I'm using friendly_id gem that converts http://localhost:3000/posts/1 to http://localhost:3000/posts/titile-of-the-post .

I added impressionist to the controller and I also added is_impressionable to the model.

When I try to run @post.impression_count, the app doesn't show impressions.

Running from Rails C, I figured out that the class Impression was not registering impressionable_id: nil.

As you can see here:

irb(main):008:0> Impression.all
Impression Load (0.7ms) SELECT impressions.* FROM impressions
=> [#<Impression id: 1, impressionable_type: "Post", impressionable_id: nil, user_id: nil, controller_name: "posts", action_name: "index", view_name: nil, request_hash: "82cb89bf5d40fc59a9358fe7cfa29ab9cee227f38ea9f10607a...", ip_address: "127.0.0.1", session_hash: "c1a3dd4fd1b4d2f725a230448027d2bf", message: nil, referrer: nil, created_at: "2011-12-25 22:02:25", updated_at: "2011-12-25 22:02:25">, #<Impression id: 2, impressionable_type: "Post", impressionable_id: 0, user_id: nil, controller_name: "posts", action_name: "show", view_name: nil, request_hash: "d6e0c423c5e4e7b361fd124cff5a6ee160d8509cc72768cee23...", ip_address: "127.0.0.1", session_hash: "c1a3dd4fd1b4d2f725a230448027d2bf", message: nil, referrer: "http://localhost:3000/", created_at: "2011-12-25 22:02:28", updated_at: "2011-12-25 22:02:28">, #<Impression id: 3, impressionable_type: "Post", impressionable_id: 0, user_id: nil, controller_name: "posts", action_name: "show", view_name: nil, request_hash: "b6749596053caf0257ef95a5fe41257ddc3672989c2144bef6b...", ip_address: "127.0.0.1", session_hash: "c1a3dd4fd1b4d2f725a230448027d2bf", message: nil, referrer: "http://localhost:3000/", created_at: "2011-12-25 22:04:03", updated_at: "2011-12-25 22:04:03">, #<Impression id: 4, impressionable_type: "Post", impressionable_id: 0, user_id: nil, controller_name: "posts", action_name: "show", view_name: nil, request_hash: "c505f1790072876b5cd0fa9db0030352dda5635cda94b262286...", ip_address: "127.0.0.1", session_hash: "c1a3dd4fd1b4d2f725a230448027d2bf", message: nil, referrer: "http://localhost:3000/", created_at: "2011-12-25 22:04:07", updated_at: "2011-12-25 22:04:07">, #<Impression id: 5, impressionable_type: "Post", impressionable_id: 0, user_id: nil, controller_name: "posts", action_name: "show", view_name: nil, request_hash: "2c3a245191a1c7399c33c98215ff4e31907fcbb0071d482df6c...", ip_address: "127.0.0.1", session_hash: "c1a3dd4fd1b4d2f725a230448027d2bf", message: nil, referrer: "http://localhost:3000/", created_at: "2011-12-25 22:07:52", updated_at: "2011-12-25 22:07:52">, #<Impression id: 6, impressionable_type: "Post", impressionable_id: 0, user_id: nil, controller_name: "posts", action_name: "show", view_name: nil, request_hash: "0a2831ccf5877b2ef70896e902b9891dc7354e00dbb9def2298...", ip_address: "127.0.0.1", session_hash: "c1a3dd4fd1b4d2f725a230448027d2bf", message: nil, referrer: "http://localhost:3000/", created_at: "2011-12-25 22:08:47", updated_at: "2011-12-25 22:08:47">]
irb(main):009:0>

I have issues with Friendly_ID that changes the way Rails 3.1 works, so all the helpers instead of request id from the instance model, it requests whatever slug from that object. I guess friendly_id is sending a string instead of the an id, but I don't know where to change that specific behavior.

Impressionist doesn't work with sitemap_notifier

Using the latest version of impressionist gem 'impressionist', '~> 1.2.0', it will not work with sitemap_notifier version 1.0.0. The error received is

.rvm/gems/ruby-1.9.3-p194/gems/activerecord-3.2.11/lib/active_record/dynamic_matchers.rb:55:in method_missing': undefined local variable or methodis_impressionable' for #Class:0x007f8902c8e690 (NameError)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.