visit-counter 0.0.3 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -35,6 +35,22 @@ You can also do something like this:
35
35
 
36
36
  this will override the counter_name method to read the live counter (from both database and the NoSQL storage) and add a increase_counter_name method for upping the counter by 1 (in the NoSQL and/or persist to DB when needed)
37
37
 
38
+ ##Thresholds
39
+
40
+ the default behaviour of visit counter is that once the visits pass 30% of the staged number, the visit counter stages the changes and nullifies the delta. You can, however, tweak that method. including VisitCounter in a class creates two class attribute_accessors, one named visit_counter_threshold_method, the other visit_counter_threshold.
41
+ visit_counter_threshold_method accepts either :static or :percent (the default), the threshold is either the decimal percent (0.1 for 10%) or an integer for :static. in case of the :static method you will percist to the DB once every (threshold) times the counter goes up.
42
+
43
+ so you might want to do something like that:
44
+
45
+ class Foo < ActiveRecord::Base
46
+ include VisitCounter
47
+ cached_counter :counter_name
48
+ visit_counter_threshold_method = :static
49
+ visit_counter_threshold = 100
50
+ end
51
+
52
+ if you want the counter to persist to database once every 100 views.
53
+
38
54
  ## Contributing
39
55
 
40
56
  1. Fork it
@@ -1,3 +1,3 @@
1
1
  module VisitCounter
2
- VERSION = "0.0.3"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -1,6 +1,12 @@
1
1
  module VisitCounter
2
2
 
3
3
  def self.included(base)
4
+ base.class_eval do
5
+ class << self
6
+ #defining class instance attributes
7
+ attr_accessor :visit_counter_threshold, :visit_counter_threshold_method
8
+ end
9
+ end
4
10
  base.send(:include, InstanceMethods)
5
11
  base.send(:extend, ClassMethods)
6
12
  end
@@ -9,10 +15,9 @@ module VisitCounter
9
15
  def incr_counter(name)
10
16
  key = VisitCounter::Key.key(self, name)
11
17
  count = VisitCounter::Store.engine.incr(key)
12
- current_count = self.send(:read_attribute, name).to_i
13
- if current_count / (current_count + count).to_f < 0.7
14
- self.update_attribute(name, current_count + count)
15
- nullify_counter_cache(name)
18
+ staged_count = self.send(:read_attribute, name).to_i
19
+ if Helper.passed_limit?(self, staged_count, count, name)
20
+ Helper.persist(self, staged_count, count, name)
16
21
  end
17
22
  end
18
23
 
@@ -46,6 +51,34 @@ module VisitCounter
46
51
  incr_counter(name)
47
52
  end
48
53
  end
54
+ end
55
+
56
+ class Helper
57
+ class << self
58
+ def passed_limit?(object, staged_count, diff, name)
59
+ method = object.class.visit_counter_threshold_method || :percent
60
+ threshold = object.class.visit_counter_threshold || default_threshold(method)
49
61
 
62
+ if method.to_sym == :static
63
+ diff >= threshold
64
+ elsif method.to_sym == :percent
65
+ return true if staged_count.to_i == 0
66
+ diff.to_f / staged_count.to_f >= threshold
67
+ end
68
+ end
69
+
70
+ def persist(object, staged_count, diff, name)
71
+ object.update_attribute(name, staged_count + diff)
72
+ object.nullify_counter_cache(name)
73
+ end
74
+
75
+ def default_threshold(method)
76
+ if method.to_sym == :static
77
+ 10
78
+ elsif method.to_sym == :percent
79
+ 0.3
80
+ end
81
+ end
82
+ end
50
83
  end
51
84
  end
@@ -35,16 +35,16 @@ describe VisitCounter do
35
35
  @d.counter = 100
36
36
  @d.incr_counter(:counter)
37
37
  @d.counter.should == 100
38
- 43.times do
38
+ 30.times do
39
39
  @d.incr_counter(:counter)
40
40
  end
41
- @d.counter.should == 143
41
+ @d.counter.should == 130
42
42
 
43
43
  #should still be 143, because of the percentage thingie
44
- 43.times do
44
+ 30.times do
45
45
  @d.incr_counter(:counter)
46
46
  end
47
- @d.counter.should == 143
47
+ @d.counter.should == 130
48
48
  end
49
49
  end
50
50
 
@@ -68,6 +68,48 @@ describe VisitCounter do
68
68
  end
69
69
  end
70
70
 
71
+ describe "static threshold" do
72
+ before :each do
73
+ @d = DummyObject.new
74
+ @d.stub!(:id).and_return(1)
75
+ @d.nullify_counter_cache(:counter)
76
+ DummyObject.visit_counter_threshold_method = :static
77
+ end
78
+
79
+ it "should persist after setting a static threshold of 1" do
80
+ DummyObject.visit_counter_threshold = 1
81
+ @d.counter = 10
82
+ @d.incr_counter(:counter)
83
+ @d.counter.should == 11
84
+ end
85
+
86
+ it "should not persist after setting a static threshold of 2" do
87
+ DummyObject.visit_counter_threshold = 2
88
+ @d.counter = 10
89
+ @d.incr_counter(:counter)
90
+ @d.counter.should == 10
91
+
92
+ @d.incr_counter(:counter)
93
+ @d.counter.should == 12
94
+ end
95
+ end
96
+
97
+ describe "percent threshold" do
98
+ before :each do
99
+ @d = DummyObject.new
100
+ @d.stub!(:id).and_return(1)
101
+ @d.nullify_counter_cache(:counter)
102
+ DummyObject.visit_counter_threshold_method = :percent
103
+ end
104
+
105
+ it "should persist when passing a percent" do
106
+ DummyObject.visit_counter_threshold = 0.1
107
+ @d.counter = 10
108
+ @d.incr_counter(:counter)
109
+ @d.counter.should == 11
110
+ end
111
+ end
112
+
71
113
  describe "overriding the getter" do
72
114
  before :all do
73
115
  DummyObject.cached_counter :counter
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: visit-counter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-23 00:00:00.000000000 Z
12
+ date: 2012-09-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec