Merge pull request #12 from coryschires/master

Merged in the counter caching code. Added docs for previous pull request concerning recording unique impressions
This commit is contained in:
Cory Schires 2011-11-27 11:44:22 -08:00
commit 85a714ff21
16 changed files with 275 additions and 103 deletions

1
.gitignore vendored
View File

@ -1,5 +1,4 @@
Gemfile.lock
/test_app/db/migrate/20*
/test_app/db/schema.rb
/pkg
*~

View File

@ -5,20 +5,14 @@ impressionist
A lightweight plugin that logs impressions per action or manually per model
I would not call this a stable plugin yet, although I have been running it in prod with no problems. Use at your own risk ;-)
------------------------------------------------------------------------------------------------------------------------------
NOTE: If you are upgrading from a version prior to 0.4.0, you will need to run this migration after the upgrade:
https://github.com/charlotte-ruby/impressionist/blob/master/upgrade_migrations/version_0_4_0.rb
If you don't run this migration you will receive this error: Unknown attribute : referrer
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 G Analytics and pulling data using their API. You can attach custom
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 G 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?
@ -28,7 +22,7 @@ http://www.user-agents.org/allagents.xml
Which versions of Rails and Ruby is this compatible with?
---------------------------------------------------------
Rails 3.0.x and Ruby 1.9.2 (also tested on REE 1.8.7) - Sorry, but you need to upgrade if you are using Rails 2. You know you want to anyways.. all the cool kids are doing it ;-)
Rails 3.0.4 and Ruby 1.9.2 (also tested on REE 1.8.7) - Sorry, but you need to upgrade if you are using Rails 2. You know you want to anyways.. all the cool kids are doing it ;-)
Installation
------------
@ -101,17 +95,49 @@ Usage
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 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)
8. 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)
Logging impressions for authenticated users happens automatically. If you have a current_user helper or use @current_user in your before_filter 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 => { :column_name => :my_column }
If you'd like to include only unique impressions in your count:
is_impressionable :counter_cache => { :column_name => :my_column, :unique => true }
What if I only want to record unique impressions?
-------------------------------------------------
Maybe you only care about unique impressions and would like to eliminate unnecessary database calls. 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]
Or you can use the `impressionist` method directly:
impressionist(impressionable, "some message", :unique => [:session_hash])
Development Roadmap
-------------------
@ -121,14 +147,14 @@ Development Roadmap
* AB testing integration
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.
* 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.
Copyright (c) 2011 John McAliley. See LICENSE.txt for further details.

View File

@ -1,3 +1,16 @@
class Impression < ActiveRecord::Base
belongs_to :impressionable, :polymorphic=>true
after_save :update_impressions_counter_cache
private
def update_impressions_counter_cache
impressionable_class = self.impressionable_type.constantize
if impressionable_class.counter_cache_options
resouce = impressionable_class.find(self.impressionable_id)
resouce.try(:update_counter_cache)
end
end
end

View File

@ -1,15 +1,38 @@
module Impressionist
module Impressionable
def is_impressionable
has_many :impressions, :as=>:impressionable
include InstanceMethods
def self.included(base)
base.extend ClassMethods
base.send(:include, InstanceMethods)
end
module ClassMethods
attr_accessor :cache_options
@cache_options = nil
def is_impressionable(options={})
has_many :impressions, :as=>:impressionable
@cache_options = options[:counter_cache]
end
def counter_cache_options
if @cache_options
options = { :column_name => :impressions_count, :unique => false }
options.merge!(@cache_options) if @cache_options.is_a?(Hash)
options
end
end
def counter_caching?
counter_cache_options.present?
end
end
module InstanceMethods
def impressionable?
true
end
def impressionist_count(options={})
options.reverse_merge!(:filter=>:request_hash, :start_date=>nil, :end_date=>Time.now)
imps = options[:start_date].blank? ? impressions : impressions.where("created_at>=? and created_at<=?",options[:start_date],options[:end_date])
@ -18,7 +41,14 @@ module Impressionist
end
imps.all.size
end
def update_counter_cache
cache_options = self.class.counter_cache_options
column_name = cache_options[:column_name].to_sym
count = cache_options[:unique] ? impressionist_count(:filter => :ip_address) : impressionist_count
update_attribute(column_name, count)
end
# OLD METHODS - DEPRECATE IN V0.5
def impression_count(start_date=nil,end_date=Time.now)
impressionist_count({:start_date=>start_date, :end_date=>end_date, :filter=>:all})
@ -27,14 +57,15 @@ module Impressionist
def unique_impression_count(start_date=nil,end_date=Time.now)
impressionist_count({:start_date=>start_date, :end_date=>end_date, :filter=> :request_hash})
end
def unique_impression_count_ip(start_date=nil,end_date=Time.now)
impressionist_count({:start_date=>start_date, :end_date=>end_date, :filter=> :ip_address})
end
def unique_impression_count_session(start_date=nil,end_date=Time.now)
impressionist_count({:start_date=>start_date, :end_date=>end_date, :filter=> :session_hash})
end
end
end
end

View File

@ -2,11 +2,11 @@ require "impressionist"
require "rails"
module Impressionist
class Engine < Rails::Engine
class Engine < Rails::Engine
initializer 'impressionist.extend_ar' do |app|
ActiveRecord::Base.extend Impressionist::Impressionable
ActiveRecord::Base.send(:include, Impressionist::Impressionable)
end
initializer 'impressionist.controller' do
ActiveSupport.on_load(:action_controller) do
include ImpressionistController::InstanceMethods

View File

@ -1,5 +1,5 @@
PATH
remote: /home/mio/prog/projects/impressionist
remote: /Users/coryschires/Desktop/impressionist
specs:
impressionist (0.4.0)
@ -45,7 +45,7 @@ GEM
autotest-standalone (4.5.8)
bcrypt-ruby (3.0.1)
builder (3.0.0)
capybara (1.1.1)
capybara (1.1.2)
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
@ -54,10 +54,10 @@ GEM
xpath (~> 0.1.4)
childprocess (0.2.2)
ffi (~> 1.0.6)
cucumber (1.1.1)
cucumber (1.1.3)
builder (>= 2.1.2)
diff-lcs (>= 1.1.2)
gherkin (~> 2.6.0)
gherkin (~> 2.6.7)
json (>= 1.4.6)
term-ansicolor (>= 1.0.6)
cucumber-rails (1.2.0)
@ -65,12 +65,12 @@ GEM
cucumber (>= 1.1.1)
nokogiri (>= 1.5.0)
daemons (1.0.10)
database_cleaner (0.6.7)
database_cleaner (0.7.0)
diff-lcs (1.1.3)
erubis (2.7.0)
ffi (1.0.9)
ffi (1.0.11)
gem_plugin (0.2.3)
gherkin (2.6.2)
gherkin (2.6.8)
json (>= 1.4.6)
hike (1.2.1)
i18n (0.6.0)
@ -129,10 +129,10 @@ GEM
activesupport (~> 3.0)
railties (~> 3.0)
rspec (~> 2.7.0)
rubyzip (0.9.4)
selenium-webdriver (2.10.0)
rubyzip (0.9.5)
selenium-webdriver (2.13.0)
childprocess (>= 0.2.1)
ffi (= 1.0.9)
ffi (~> 1.0.9)
json_pure
rubyzip
spork (0.8.5)

View File

@ -2,5 +2,5 @@
class DummyController < ActionController::Base
impressionist
end

View File

@ -0,0 +1,7 @@
# We don't really care about this model. It's just being used to test the uniqueness controller
# specs. Nevertheless, we need a model because the counter caching functionality expects it.
#
class Dummy < ActiveRecord::Base
self.abstract_class = true # doesn't need to be backed by an actual table
is_impressionable
end

View File

@ -0,0 +1,3 @@
class Widget < ActiveRecord::Base
is_impressionable :counter_cache => true
end

View File

@ -0,0 +1,15 @@
class CreateWidgets < ActiveRecord::Migration
def self.up
create_table :widgets do |t|
t.string :name
t.integer :impressions_count
t.timestamps
end
end
def self.down
drop_table :widgets
end
end

View File

@ -0,0 +1,37 @@
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 :controller_name
t.string :action_name
t.string :view_name
t.string :request_hash
t.string :session_hash
t.string :ip_address
t.string :message
t.string :referrer
t.timestamps
end
add_index :impressions, [:impressionable_type, :impressionable_id, :request_hash], :name => "poly_request_index", :unique => false
add_index :impressions, [:impressionable_type, :impressionable_id, :ip_address], :name => "poly_ip_index", :unique => false
add_index :impressions, [:impressionable_type, :impressionable_id, :session_hash], :name => "poly_session_index", :unique => false
add_index :impressions, [:controller_name,:action_name,:request_hash], :name => "controlleraction_request_index", :unique => false
add_index :impressions, [:controller_name,:action_name,:ip_address], :name => "controlleraction_ip_index", :unique => false
add_index :impressions, [:controller_name,:action_name,:session_hash], :name => "controlleraction_session_index", :unique => false
add_index :impressions, :user_id
end
def self.down
remove_index :impressions, :name => :poly_request_index
remove_index :impressions, :name => :poly_ip_index
remove_index :impressions, :name => :poly_session_index
remove_index :impressions, :name => :controlleraction_request_index
remove_index :impressions, :name => :controlleraction_ip_index
remove_index :impressions, :name => :controlleraction_session_index
remove_index :impressions, :user_id
drop_table :impressions
end
end

View File

@ -1,14 +1,14 @@
require 'spec_helper.rb'
describe ArticlesController do
fixtures :articles,:impressions,:posts
fixtures :articles,:impressions,:posts,:widgets
render_views
it "should make the impressionable_hash available" do
get "index"
response.body.include?("false").should eq true
end
it "should log an impression with a message" do
get "index"
Impression.all.size.should eq 12
@ -16,7 +16,7 @@ describe ArticlesController do
Article.first.impressions.last.controller_name.should eq "articles"
Article.first.impressions.last.action_name.should eq "index"
end
it "should log an impression without a message" do
get "show", :id=> 1
Impression.all.size.should eq 12
@ -24,18 +24,18 @@ describe ArticlesController do
Article.first.impressions.last.controller_name.should eq "articles"
Article.first.impressions.last.action_name.should eq "show"
end
it "should log the user_id if user is authenticated (@current_user before_filter method)" do
session[:user_id] = 123
get "show", :id=> 1
Article.first.impressions.last.user_id.should eq 123
end
it "should not log the user_id if user is authenticated" do
get "show", :id=> 1
Article.first.impressions.last.user_id.should eq nil
end
it "should log the request_hash, ip_address, referrer and session_hash" do
get "show", :id=> 1
Impression.last.request_hash.size.should eq 64
@ -43,13 +43,13 @@ describe ArticlesController do
Impression.last.session_hash.size.should eq 32
Impression.last.referrer.should eq nil
end
it "should log the referrer when you click a link" do
visit article_url(Article.first)
click_link "Same Page"
Impression.last.referrer.should eq "http://test.host/articles/1"
end
end
end
describe PostsController do
it "should log impression at the action level" do
@ -60,7 +60,7 @@ describe PostsController do
Impression.last.impressionable_type.should eq "Post"
Impression.last.impressionable_id.should eq 1
end
it "should log the user_id if user is authenticated (current_user helper method)" do
session[:user_id] = 123
get "show", :id=> 1
@ -69,6 +69,12 @@ describe PostsController do
end
describe WidgetsController do
before(:each) do
@widget = Widget.find(1)
Widget.stub(:find).and_return(@widget)
end
it "should log impression at the per action level" do
get "show", :id=> 1
Impression.all.size.should eq 12
@ -77,17 +83,17 @@ describe WidgetsController do
get "new"
Impression.all.size.should eq 13
end
it "should not log impression when user-agent is in wildcard list" do
request.stub!(:user_agent).and_return('somebot')
get "show", :id=> 1
Impression.all.size.should eq 11
end
it "should not log impression when user-agent is in the bot list" do
request.stub!(:user_agent).and_return('Acoon Robot v1.50.001')
get "show", :id=> 1
Impression.all.size.should eq 11
Impression.all.size.should eq 11
end
describe "impressionist unique options" do
@ -117,4 +123,3 @@ describe WidgetsController do
end
end

View File

@ -2,19 +2,19 @@ require "spec_helper.rb"
# we use the posts controller as it uses the impressionsist module. any such controller would do.
describe DummyController do
before do
@impression_count = Impression.all.size
end
describe "impressionist filter uniqueness" do
@impression_count = Impression.all.size
end
describe "impressionist filter uniqueness" do
it "should ignore uniqueness if not requested" do
controller.impressionist_subapp_filter(nil, nil)
controller.impressionist_subapp_filter(nil, nil)
Impression.should have(@impression_count + 2).records
end
it "should recognize unique session" do
# the following line was necessary as session hash returned a binary string (ASCII-8BIT encoded)
controller.stub!(:session_hash).and_return(request.session_options[:id].encode("ISO-8859-1"))
@ -22,58 +22,58 @@ describe DummyController do
controller.impressionist_subapp_filter(nil, [:session_hash])
Impression.should have(@impression_count + 1).records
end
it "should recognize unique ip" do
controller.request.stub!(:remote_ip).and_return("1.2.3.4")
controller.impressionist_subapp_filter(nil, [:ip_address])
controller.impressionist_subapp_filter(nil, [:ip_address])
Impression.should have(@impression_count + 1).records
end
it "should recognize unique request" do
controller.impressionist_subapp_filter(nil, [:request_hash])
controller.impressionist_subapp_filter(nil, [:request_hash])
Impression.should have(@impression_count + 1).records
end
it "should recognize unique action" do
controller.stub!(:action_name).and_return("test_action")
controller.impressionist_subapp_filter(nil, [:action_name])
controller.impressionist_subapp_filter(nil, [:action_name])
Impression.should have(@impression_count + 1).records
end
it "should recognize unique controller" do
controller.stub!(:controller_name).and_return("test_controller")
controller.stub!(:controller_name).and_return("post")
controller.impressionist_subapp_filter(nil, [:controller_name])
controller.impressionist_subapp_filter(nil, [:controller_name])
Impression.should have(@impression_count + 1).records
end
it "should recognize unique user" do
it "should recognize unique user" do
controller.stub!(:user_id).and_return(42)
controller.impressionist_subapp_filter(nil, [:user_id])
controller.impressionist_subapp_filter(nil, [:user_id])
Impression.should have(@impression_count + 1).records
end
it "should recognize unique referer" do
controller.request.stub!(:referer).and_return("http://foo/bar")
controller.impressionist_subapp_filter(nil, [:referrer])
controller.impressionist_subapp_filter(nil, [:referrer])
Impression.should have(@impression_count + 1).records
end
it "should recognize unique id" do
controller.stub!(:params).and_return({:id => "666"}) # for correct impressionable id in filter
controller.impressionist_subapp_filter(nil, [:impressionable_id])
controller.impressionist_subapp_filter(nil, [:impressionable_id])
Impression.should have(@impression_count + 1).records
end
# extra redundant test for important controller and action combination.
it "should recognize different controller and action" do
controller.stub!(:controller_name).and_return("test_controller")
controller.stub!(:controller_name).and_return("post")
controller.stub!(:action_name).and_return("test_action")
controller.impressionist_subapp_filter(nil, [:controller_name, :action_name])
controller.impressionist_subapp_filter(nil, [:controller_name, :action_name])
@ -82,12 +82,12 @@ describe DummyController do
controller.impressionist_subapp_filter(nil, [:controller_name, :action_name])
controller.impressionist_subapp_filter(nil, [:controller_name, :action_name])
Impression.should have(@impression_count + 2).records
controller.stub!(:controller_name).and_return("another_controller")
controller.stub!(:controller_name).and_return("article")
controller.impressionist_subapp_filter(nil, [:controller_name, :action_name])
controller.impressionist_subapp_filter(nil, [:controller_name, :action_name])
Impression.should have(@impression_count + 3).records
end
it "should recognize different action" do
controller.stub!(:action_name).and_return("test_action")
controller.impressionist_subapp_filter(nil, [:action_name])
@ -98,18 +98,18 @@ describe DummyController do
controller.impressionist_subapp_filter(nil, [:action_name])
Impression.should have(@impression_count + 2).records
end
it "should recognize different controller" do
controller.stub!(:controller_name).and_return("test_controller")
controller.stub!(:controller_name).and_return("post")
controller.impressionist_subapp_filter(nil, [:controller_name])
controller.impressionist_subapp_filter(nil, [:controller_name])
Impression.should have(@impression_count + 1).records
controller.stub!(:controller_name).and_return("another_controller")
controller.stub!(:controller_name).and_return("article")
controller.impressionist_subapp_filter(nil, [:controller_name])
controller.impressionist_subapp_filter(nil, [:controller_name])
Impression.should have(@impression_count + 2).records
end
it "should recognize different session" do
controller.stub!(:session_hash).and_return("foo")
controller.impressionist_subapp_filter(nil, [:session_hash])
@ -120,7 +120,7 @@ describe DummyController do
controller.impressionist_subapp_filter(nil, [:session_hash])
Impression.should have(@impression_count + 2).records
end
it "should recognize different ip" do
controller.request.stub!(:remote_ip).and_return("1.2.3.4")
controller.impressionist_subapp_filter(nil, [:ip_address])
@ -131,7 +131,7 @@ describe DummyController do
controller.impressionist_subapp_filter(nil, [:ip_address])
Impression.should have(@impression_count + 2).records
end
it "should recognize different referer" do
controller.request.stub!(:referer).and_return("http://foo/bar")
controller.impressionist_subapp_filter(nil, [:referrer])
@ -142,7 +142,7 @@ describe DummyController do
controller.impressionist_subapp_filter(nil, [:referrer])
Impression.should have(@impression_count + 2).records
end
it "should recognize different id" do
controller.stub!(:params).and_return({:id => "666"}) # for correct impressionable id in filter
controller.impressionist_subapp_filter(nil, [:impressionable_type, :impressionable_id])
@ -152,7 +152,7 @@ describe DummyController do
controller.impressionist_subapp_filter(nil, [:impressionable_type, :impressionable_id])
Impression.should have(@impression_count + 2).records
end
it "should recognize combined uniqueness" do
controller.stub!(:action_name).and_return("test_action")
controller.impressionist_subapp_filter(nil, [:ip_address, :request_hash, :action_name])
@ -165,7 +165,7 @@ describe DummyController do
controller.impressionist_subapp_filter(nil, [:request_hash])
Impression.should have(@impression_count + 1).records
end
it "should recognize combined non-uniqueness" do
controller.stub!(:action_name).and_return(nil)
controller.impressionist_subapp_filter(nil, [:ip_address, :action_name])
@ -174,21 +174,21 @@ describe DummyController do
controller.stub!(:action_name).and_return("another_action")
controller.impressionist_subapp_filter(nil, [:ip_address, :action_name])
Impression.should have(@impression_count + 3).records
end
end
end
describe "impressionist method uniqueness for impressionables" do
describe "impressionist method uniqueness for impressionables" do
# in this test we reuse the post model. might break if model changes.
it "should ignore uniqueness if not requested" do
impressionable = Post.create
controller.impressionist impressionable
controller.impressionist impressionable
Impression.should have(@impression_count + 2).records
end
it "should recognize unique session" do
# the following line was necessary as session hash returned a binary string (ASCII-8BIT encoded)
controller.stub!(:session_hash).and_return(request.session_options[:id].encode("ISO-8859-1"))
@ -197,7 +197,7 @@ describe DummyController do
controller.impressionist(impressionable, nil, :unique => [:session_hash])
Impression.should have(@impression_count + 1).records
end
it "should recognize unique ip" do
controller.request.stub!(:remote_ip).and_return("1.2.3.4")
impressionable = Post.create
@ -205,22 +205,22 @@ describe DummyController do
controller.impressionist(impressionable, nil, :unique => [:ip_address])
Impression.should have(@impression_count + 1).records
end
it "should recognize unique request" do
impressionable = Post.create
controller.impressionist(impressionable, nil, :unique => [:request_hash])
controller.impressionist(impressionable, nil, :unique => [:request_hash])
Impression.should have(@impression_count + 1).records
end
it "should recognize unique user" do
it "should recognize unique user" do
controller.stub!(:user_id).and_return(666)
impressionable = Post.create
controller.impressionist(impressionable, nil, :unique => [:user_id])
controller.impressionist(impressionable, nil, :unique => [:user_id])
Impression.should have(@impression_count + 1).records
end
it "should recognize unique referer" do
controller.request.stub!(:referer).and_return("http://foo/bar")
impressionable = Post.create
@ -228,7 +228,7 @@ describe DummyController do
controller.impressionist(impressionable, nil, :unique => [:referrer])
Impression.should have(@impression_count + 1).records
end
it "should recognize different session" do
impressionable = Post.create
controller.stub!(:session_hash).and_return("foo")
@ -240,7 +240,7 @@ describe DummyController do
controller.impressionist(impressionable, nil, :unique => [:session_hash])
Impression.should have(@impression_count + 2).records
end
it "should recognize different ip" do
controller.request.stub!(:remote_ip).and_return("1.2.3.4")
impressionable = Post.create
@ -252,7 +252,7 @@ describe DummyController do
controller.impressionist(impressionable, nil, :unique => [:ip_address])
Impression.should have(@impression_count + 2).records
end
it "should recognize different user" do
impressionable = Post.create
controller.stub!(:user_id).and_return(666)
@ -264,7 +264,7 @@ describe DummyController do
controller.impressionist(impressionable, nil, :unique => [:user_id])
Impression.should have(@impression_count + 2).records
end
it "should recognize combined uniqueness" do
impressionable = Post.create
controller.stub!(:session_hash).and_return("foo")
@ -278,7 +278,7 @@ describe DummyController do
controller.impressionist(impressionable, nil, :unique => [:request_hash])
Impression.should have(@impression_count + 1).records
end
it "should recognize combined non-uniqueness" do
impressionable = Post.create
controller.stub!(:session_hash).and_return(nil)
@ -289,11 +289,11 @@ describe DummyController do
controller.impressionist(impressionable, nil, :unique => [:ip_address, :session_hash])
Impression.should have(@impression_count + 3).records
end
end
describe "impressionist filter and method uniqueness" do
it "should recognize uniqueness" do
impressionable = Post.create
controller.stub!(:controller_name).and_return("posts") # for correct impressionable type in filter
@ -305,8 +305,8 @@ describe DummyController do
controller.impressionist(impressionable, nil, :unique => [:ip_address, :request_hash, :session_hash])
Impression.should have(@impression_count + 1).records
end
end
end

4
test_app/spec/fixtures/widgets.yml vendored Normal file
View File

@ -0,0 +1,4 @@
one:
id: 1
name: A Widget
impressions_count: 0

View File

@ -0,0 +1,30 @@
require 'spec_helper'
describe Impression do
fixtures :widgets
before(:each) do
@widget = Widget.find(1)
Impression.destroy_all
end
describe "self#counter_caching?" do
it "should know when counter caching is enabled" do
Widget.should be_counter_caching
end
it "should know when counter caching is disabled" do
Article.should_not be_counter_caching
end
end
describe "#update_counter_cache" do
it "should update the counter cache column to reflect the correct number of impressions" do
lambda {
Impression.create(:impressionable_type => @widget.class.name, :impressionable_id => @widget.id)
@widget.reload
}.should change(@widget, :impressions_count).from(0).to(1)
end
end
end

View File

@ -49,6 +49,8 @@ describe Impression do
@article.impressionist_count(:filter=>:session_hash).should eq 7
end
#OLD COUNT METHODS. DEPRECATE SOON
it "should return the impression count with no date range specified" do
@article.impression_count.should eq 11