Count view only once in the same browser

openid
Marcin Kulik 11 years ago
parent 7a3bc80340
commit 013eade63c

@ -2,7 +2,6 @@ class AsciicastsController < ApplicationController
PER_PAGE = 15
before_filter :load_resource, :only => [:show, :raw, :edit, :update, :destroy]
before_filter :count_view, :only => [:show]
before_filter :ensure_authenticated!, :only => [:edit, :update, :destroy]
before_filter :ensure_owner!, :only => [:edit, :update, :destroy]
@ -33,6 +32,7 @@ class AsciicastsController < ApplicationController
format.html do
@asciicast = AsciicastDecorator.new(@asciicast)
@title = @asciicast.title
ViewCounter.new(@asciicast, cookies).increment
respond_with @asciicast
end
@ -78,12 +78,6 @@ class AsciicastsController < ApplicationController
@asciicast = Asciicast.find(params[:id])
end
def count_view
unless request.xhr?
Asciicast.increment_counter :views_count, @asciicast.id
end
end
def ensure_owner!
if current_user != @asciicast.user
redirect_to asciicast_path(@asciicast), :alert => "You can't do that."

@ -0,0 +1,22 @@
class ViewCounter
attr_reader :asciicast, :storage
def initialize(asciicast, storage)
@asciicast = asciicast
@storage = storage
end
def increment
unless storage[key]
Asciicast.increment_counter(:views_count, asciicast.id)
asciicast.reload
storage[key] = '1'
end
end
private
def key
@key ||= :"asciicast_#{asciicast.id}_viewed"
end
end

@ -64,9 +64,14 @@ describe AsciicastsController do
end
context 'for html request' do
let(:view_counter) { mock('view_counter') }
before do
AsciicastDecorator.should_receive(:new).with(asciicast).
and_return(asciicast)
ViewCounter.should_receive(:new).with(asciicast, cookies).
and_return(view_counter)
view_counter.should_receive(:increment)
get :show, :id => asciicast.id, :format => :html
end
@ -82,6 +87,7 @@ describe AsciicastsController do
before do
AsciicastJSONDecorator.should_receive(:new).with(asciicast).
and_return(asciicast)
ViewCounter.should_not_receive(:new)
get :show, :id => asciicast.id, :format => :json
end

@ -0,0 +1,27 @@
require 'spec_helper'
describe ViewCounter do
let(:view_counter) { ViewCounter.new(asciicast, storage) }
let(:asciicast) { create(:asciicast) }
let(:storage) { {} }
describe '#increment' do
context "when called for the first time" do
it "increments the views_count" do
expect { view_counter.increment }.
to change(asciicast, :views_count).by(1)
end
end
context "when called for the second time" do
before do
view_counter.increment
end
it "doesn't increment the views_count" do
expect { view_counter.increment }.
not_to change(asciicast, :views_count)
end
end
end
end
Loading…
Cancel
Save