acts_as_votable 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +9 -6
  3. data/.rubocop.yml +121 -0
  4. data/.travis.yml +12 -23
  5. data/Appraisals +13 -0
  6. data/Gemfile +3 -14
  7. data/README.markdown +80 -13
  8. data/Rakefile +6 -4
  9. data/acts_as_votable.gemspec +12 -5
  10. data/gemfiles/.bundle/config +2 -0
  11. data/gemfiles/rails_4.gemfile +7 -0
  12. data/gemfiles/rails_4.gemfile.lock +159 -0
  13. data/gemfiles/rails_5.gemfile +7 -0
  14. data/gemfiles/rails_5.gemfile.lock +166 -0
  15. data/gemfiles/rails_5_1.gemfile +7 -0
  16. data/gemfiles/rails_5_1.gemfile.lock +166 -0
  17. data/lib/acts_as_votable.rb +9 -9
  18. data/lib/acts_as_votable/cacheable.rb +174 -0
  19. data/lib/acts_as_votable/extenders/controller.rb +3 -4
  20. data/lib/acts_as_votable/extenders/votable.rb +17 -6
  21. data/lib/acts_as_votable/extenders/voter.rb +4 -6
  22. data/lib/acts_as_votable/helpers/words.rb +7 -10
  23. data/lib/acts_as_votable/version.rb +3 -1
  24. data/lib/acts_as_votable/votable.rb +50 -187
  25. data/lib/acts_as_votable/vote.rb +10 -12
  26. data/lib/acts_as_votable/voter.rb +52 -53
  27. data/lib/generators/acts_as_votable/migration/migration_generator.rb +19 -4
  28. data/lib/generators/acts_as_votable/migration/templates/active_record/{migration.rb → migration.erb} +1 -6
  29. data/spec/factories/votable.rb +6 -0
  30. data/spec/factories/votable_cache.rb +6 -0
  31. data/spec/factories/votable_cache_update_attributes.rb +6 -0
  32. data/spec/factories/votable_cache_update_columns.rb +6 -0
  33. data/spec/factories/votable_child_of_sti_not_votable.rb +6 -0
  34. data/spec/factories/votable_child_of_sti_votable.rb +6 -0
  35. data/spec/factories/votable_voter.rb +6 -0
  36. data/spec/factories/vote.rb +6 -0
  37. data/spec/factories/voter.rb +6 -0
  38. data/spec/generators/active_record_generator_spec.rb +13 -0
  39. data/spec/shared_example/votable_model.rb +506 -0
  40. data/spec/shared_example/voter_model.rb +280 -0
  41. data/spec/spec_helper.rb +28 -18
  42. data/spec/support/factory_girl.rb +10 -0
  43. data/spec/votable_spec.rb +10 -9
  44. data/spec/votable_voter_spec.rb +12 -12
  45. data/spec/voter_spec.rb +9 -10
  46. data/spec/words_spec.rb +9 -12
  47. metadata +98 -27
  48. data/spec/shared_example/votable_model_spec.rb +0 -421
  49. data/spec/shared_example/voter_model_spec.rb +0 -279
@@ -1,21 +1,21 @@
1
- require 'active_record'
2
- require 'active_support/inflector'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record"
4
+ require "active_support/inflector"
3
5
 
4
6
  $LOAD_PATH.unshift(File.dirname(__FILE__))
5
7
 
6
8
  module ActsAsVotable
7
-
8
9
  if defined?(ActiveRecord::Base)
9
- require 'acts_as_votable/extenders/votable'
10
- require 'acts_as_votable/extenders/voter'
11
- require 'acts_as_votable/vote'
10
+ require "acts_as_votable/extenders/votable"
11
+ require "acts_as_votable/extenders/voter"
12
+ require "acts_as_votable/vote"
12
13
  ActiveRecord::Base.extend ActsAsVotable::Extenders::Votable
13
14
  ActiveRecord::Base.extend ActsAsVotable::Extenders::Voter
14
15
  end
15
-
16
16
  end
17
17
 
18
- require 'acts_as_votable/extenders/controller'
18
+ require "acts_as_votable/extenders/controller"
19
19
  ActiveSupport.on_load(:action_controller) do
20
20
  include ActsAsVotable::Extenders::Controller
21
- end
21
+ end
@@ -0,0 +1,174 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActsAsVotable
4
+ module Cacheable
5
+ def scope_cache_field(field, vote_scope)
6
+ return field if vote_scope.nil?
7
+
8
+ case field
9
+ when :cached_votes_total=
10
+ "cached_scoped_#{vote_scope}_votes_total="
11
+ when :cached_votes_total
12
+ "cached_scoped_#{vote_scope}_votes_total"
13
+ when :cached_votes_up=
14
+ "cached_scoped_#{vote_scope}_votes_up="
15
+ when :cached_votes_up
16
+ "cached_scoped_#{vote_scope}_votes_up"
17
+ when :cached_votes_down=
18
+ "cached_scoped_#{vote_scope}_votes_down="
19
+ when :cached_votes_down
20
+ "cached_scoped_#{vote_scope}_votes_down"
21
+ when :cached_votes_score=
22
+ "cached_scoped_#{vote_scope}_votes_score="
23
+ when :cached_votes_score
24
+ "cached_scoped_#{vote_scope}_votes_score"
25
+ when :cached_weighted_total
26
+ "cached_weighted_#{vote_scope}_total"
27
+ when :cached_weighted_total=
28
+ "cached_weighted_#{vote_scope}_total="
29
+ when :cached_weighted_score
30
+ "cached_weighted_#{vote_scope}_score"
31
+ when :cached_weighted_score=
32
+ "cached_weighted_#{vote_scope}_score="
33
+ when :cached_weighted_average
34
+ "cached_weighted_#{vote_scope}_average"
35
+ when :cached_weighted_average=
36
+ "cached_weighted_#{vote_scope}_average="
37
+ end
38
+ end
39
+
40
+ def update_cached_votes(vote_scope = nil)
41
+ updates = {}
42
+
43
+ if self.respond_to?(:cached_votes_total=)
44
+ updates[:cached_votes_total] = count_votes_total(true)
45
+ end
46
+
47
+ if self.respond_to?(:cached_votes_up=)
48
+ updates[:cached_votes_up] = count_votes_up(true)
49
+ end
50
+
51
+ if self.respond_to?(:cached_votes_down=)
52
+ updates[:cached_votes_down] = count_votes_down(true)
53
+ end
54
+
55
+ if self.respond_to?(:cached_votes_score=)
56
+ updates[:cached_votes_score] = (
57
+ (updates[:cached_votes_up] || count_votes_up(true)) -
58
+ (updates[:cached_votes_down] || count_votes_down(true))
59
+ )
60
+ end
61
+
62
+ if self.respond_to?(:cached_weighted_total=)
63
+ updates[:cached_weighted_total] = weighted_total(true)
64
+ end
65
+
66
+ if self.respond_to?(:cached_weighted_score=)
67
+ updates[:cached_weighted_score] = weighted_score(true)
68
+ end
69
+
70
+ if self.respond_to?(:cached_weighted_average=)
71
+ updates[:cached_weighted_average] = weighted_average(true)
72
+ end
73
+
74
+ if vote_scope
75
+ if self.respond_to?(scope_cache_field :cached_votes_total=, vote_scope)
76
+ updates[scope_cache_field :cached_votes_total, vote_scope] = count_votes_total(true, vote_scope)
77
+ end
78
+
79
+ if self.respond_to?(scope_cache_field :cached_votes_up=, vote_scope)
80
+ updates[scope_cache_field :cached_votes_up, vote_scope] = count_votes_up(true, vote_scope)
81
+ end
82
+
83
+ if self.respond_to?(scope_cache_field :cached_votes_down=, vote_scope)
84
+ updates[scope_cache_field :cached_votes_down, vote_scope] = count_votes_down(true, vote_scope)
85
+ end
86
+
87
+ if self.respond_to?(scope_cache_field :cached_weighted_total=, vote_scope)
88
+ updates[scope_cache_field :cached_weighted_total, vote_scope] = weighted_total(true, vote_scope)
89
+ end
90
+
91
+ if self.respond_to?(scope_cache_field :cached_weighted_score=, vote_scope)
92
+ updates[scope_cache_field :cached_weighted_score, vote_scope] = weighted_score(true, vote_scope)
93
+ end
94
+
95
+ if self.respond_to?(scope_cache_field :cached_votes_score=, vote_scope)
96
+ updates[scope_cache_field :cached_votes_score, vote_scope] = (
97
+ (updates[scope_cache_field :cached_votes_up, vote_scope] || count_votes_up(true, vote_scope)) -
98
+ (updates[scope_cache_field :cached_votes_down, vote_scope] || count_votes_down(true, vote_scope))
99
+ )
100
+ end
101
+
102
+ if self.respond_to?(scope_cache_field :cached_weighted_average=, vote_scope)
103
+ updates[scope_cache_field :cached_weighted_average, vote_scope] = weighted_average(true, vote_scope)
104
+ end
105
+ end
106
+
107
+ self.send(acts_as_votable_options[:cacheable_strategy], updates) if updates.size > 0
108
+ end
109
+
110
+ # counting
111
+ def count_votes_total(skip_cache = false, vote_scope = nil)
112
+ from_cache(skip_cache, :cached_votes_total, vote_scope) do
113
+ find_votes_for(scope_or_empty_hash(vote_scope)).count
114
+ end
115
+ end
116
+
117
+ def count_votes_up(skip_cache = false, vote_scope = nil)
118
+ from_cache(skip_cache, :cached_votes_up, vote_scope) do
119
+ get_up_votes(vote_scope: vote_scope).count
120
+ end
121
+ end
122
+
123
+ def count_votes_down(skip_cache = false, vote_scope = nil)
124
+ from_cache(skip_cache, :cached_votes_down, vote_scope) do
125
+ get_down_votes(vote_scope: vote_scope).count
126
+ end
127
+ end
128
+
129
+ def count_votes_score(skip_cache = false, vote_scope = nil)
130
+ from_cache(skip_cache, :cached_votes_score, vote_scope) do
131
+ ups = count_votes_up(true, vote_scope)
132
+ downs = count_votes_down(true, vote_scope)
133
+ ups - downs
134
+ end
135
+ end
136
+
137
+ def weighted_total(skip_cache = false, vote_scope = nil)
138
+ from_cache(skip_cache, :cached_weighted_total, vote_scope) do
139
+ ups = get_up_votes(vote_scope: vote_scope).sum(:vote_weight)
140
+ downs = get_down_votes(vote_scope: vote_scope).sum(:vote_weight)
141
+ ups + downs
142
+ end
143
+ end
144
+
145
+ def weighted_score(skip_cache = false, vote_scope = nil)
146
+ from_cache(skip_cache, :cached_weighted_score, vote_scope) do
147
+ ups = get_up_votes(vote_scope: vote_scope).sum(:vote_weight)
148
+ downs = get_down_votes(vote_scope: vote_scope).sum(:vote_weight)
149
+ ups - downs
150
+ end
151
+ end
152
+
153
+ def weighted_average(skip_cache = false, vote_scope = nil)
154
+ from_cache(skip_cache, :cached_weighted_average, vote_scope) do
155
+ count = count_votes_total(skip_cache, vote_scope).to_i
156
+ if count > 0
157
+ weighted_score(skip_cache, vote_scope).to_f / count
158
+ else
159
+ 0.0
160
+ end
161
+ end
162
+ end
163
+
164
+ private
165
+
166
+ def from_cache(skip_cache, cached_method, vote_scope)
167
+ if !skip_cache && respond_to?(scope_cache_field(cached_method, vote_scope))
168
+ send(scope_cache_field(cached_method, vote_scope))
169
+ else
170
+ yield
171
+ end
172
+ end
173
+ end
174
+ end
@@ -1,19 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActsAsVotable
2
4
  module Extenders
3
-
4
5
  module Controller
5
-
6
6
  def voter_params(params_object = params[:vote])
7
7
  params_object.permit(:votable_id, :votable_type,
8
8
  :voter_id, :voter_type,
9
9
  :votable, :voter,
10
10
  :vote_flag, :vote_scope)
11
11
  end
12
-
12
+
13
13
  def votable_params(params_object = params[:vote])
14
14
  params_object.permit(:vote_registered)
15
15
  end
16
-
17
16
  end
18
17
  end
19
18
  end
@@ -1,25 +1,36 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActsAsVotable
2
4
  module Extenders
3
-
4
5
  module Votable
6
+ ALLOWED_CACHEABLE_STRATEGIES = %i[update_attributes update_columns]
5
7
 
6
8
  def votable?
7
9
  false
8
10
  end
9
11
 
10
- def acts_as_votable
11
- require 'acts_as_votable/votable'
12
+ def acts_as_votable(args = {})
13
+ require "acts_as_votable/votable"
12
14
  include ActsAsVotable::Votable
13
15
 
16
+ if args.key?(:cacheable_strategy) && !ALLOWED_CACHEABLE_STRATEGIES.include?(args[:cacheable_strategy])
17
+ raise ArgumentError, args[:cacheable_strategy]
18
+ end
19
+
20
+ define_method :acts_as_votable_options do
21
+ self.class.instance_variable_get("@acts_as_votable_options")
22
+ end
23
+
14
24
  class_eval do
25
+ @acts_as_votable_options = {
26
+ cacheable_strategy: :update_attributes
27
+ }.merge(args)
28
+
15
29
  def self.votable?
16
30
  true
17
31
  end
18
32
  end
19
-
20
33
  end
21
-
22
34
  end
23
-
24
35
  end
25
36
  end
@@ -1,14 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActsAsVotable
2
4
  module Extenders
3
-
4
5
  module Voter
5
-
6
6
  def voter?
7
7
  false
8
8
  end
9
9
 
10
- def acts_as_voter(*args)
11
- require 'acts_as_votable/voter'
10
+ def acts_as_voter(*_args)
11
+ require "acts_as_votable/voter"
12
12
  include ActsAsVotable::Voter
13
13
 
14
14
  class_eval do
@@ -16,9 +16,7 @@ module ActsAsVotable
16
16
  true
17
17
  end
18
18
  end
19
-
20
19
  end
21
-
22
20
  end
23
21
  end
24
22
  end
@@ -1,36 +1,33 @@
1
- module ActsAsVotable::Helpers
1
+ # frozen_string_literal: true
2
2
 
3
- # this helper provides methods that help find what words are
3
+ module ActsAsVotable::Helpers
4
+ # this helper provides methods that help find what words are
4
5
  # up votes and what words are down votes
5
6
  #
6
- # It can be called
7
+ # It can be called
7
8
  #
8
9
  # votable_object.votable_words.that_mean_true
9
10
  #
10
11
  module Words
11
-
12
12
  def votable_words
13
13
  VotableWords
14
14
  end
15
-
16
15
  end
17
16
 
18
17
  class VotableWords
19
-
20
18
  def self.that_mean_true
21
- ['up', 'upvote', 'like', 'liked', 'positive', 'yes', 'good', 'true', 1, true]
19
+ ["up", "upvote", "like", "liked", "positive", "yes", "good", "agree", "true", 1, true]
22
20
  end
23
21
 
24
22
  def self.that_mean_false
25
- ['down', 'downvote', 'dislike', 'disliked', 'negative', 'no', 'bad', 'false', 0, false]
23
+ ["down", "downvote", "dislike", "disliked", "negative", "no", "bad", "disagree", "false", 0, false]
26
24
  end
27
25
 
28
26
  # check is word is a true or bad vote
29
27
  # if the word is unknown, then it counts it as a true/good
30
28
  # vote. this exists to allow all voting to be good by default
31
- def self.meaning_of word
29
+ def self.meaning_of(word)
32
30
  !that_mean_false.include?(word)
33
31
  end
34
-
35
32
  end
36
33
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActsAsVotable
2
- VERSION = "0.10.0"
4
+ VERSION = "0.11.0"
3
5
  end
@@ -1,39 +1,41 @@
1
- require 'acts_as_votable/helpers/words'
1
+ # frozen_string_literal: true
2
+
3
+ require "acts_as_votable/helpers/words"
4
+ require "acts_as_votable/cacheable"
2
5
 
3
6
  module ActsAsVotable
4
7
  module Votable
5
-
6
8
  include Helpers::Words
9
+ include Cacheable
7
10
 
8
- def self.included base
9
-
11
+ def self.included(base)
10
12
  # allow the user to define these himself
11
13
  aliases = {
12
14
 
13
- :vote_up => [
14
- :up_by, :upvote_by, :like_by, :liked_by,
15
+ vote_up: [
16
+ :up_by, :upvote_by, :like_by, :liked_by,
15
17
  :up_from, :upvote_from, :upvote_by, :like_from, :liked_from, :vote_from
16
18
  ],
17
19
 
18
- :vote_down => [
20
+ vote_down: [
19
21
  :down_by, :downvote_by, :dislike_by, :disliked_by,
20
22
  :down_from, :downvote_from, :downvote_by, :dislike_by, :disliked_by
21
23
  ],
22
24
 
23
- :get_up_votes => [
25
+ get_up_votes: [
24
26
  :get_true_votes, :get_ups, :get_upvotes, :get_likes, :get_positives, :get_for_votes,
25
27
  ],
26
28
 
27
- :get_down_votes => [
29
+ get_down_votes: [
28
30
  :get_false_votes, :get_downs, :get_downvotes, :get_dislikes, :get_negatives
29
31
  ],
30
- :unvote_by => [
32
+ unvote_by: [
31
33
  :unvote_up, :unvote_down, :unliked_by, :undisliked_by
32
34
  ]
33
35
  }
34
36
 
35
37
  base.class_eval do
36
- has_many :votes_for, :class_name => 'ActsAsVotable::Vote', :as => :votable, :dependent => :destroy do
38
+ has_many :votes_for, class_name: "ActsAsVotable::Vote", as: :votable, dependent: :destroy do
37
39
  def voters
38
40
  includes(:voter).map(&:voter)
39
41
  end
@@ -56,17 +58,16 @@ module ActsAsVotable
56
58
 
57
59
  def default_conditions
58
60
  {
59
- :votable_id => self.id,
60
- :votable_type => self.class.base_class.name.to_s
61
+ votable_id: self.id,
62
+ votable_type: self.class.base_class.name.to_s
61
63
  }
62
64
  end
63
65
 
64
66
  # voting
65
- def vote_by args = {}
66
-
67
+ def vote_by(args = {})
67
68
  options = {
68
- :vote => true,
69
- :vote_scope => nil
69
+ vote: true,
70
+ vote_scope: nil
70
71
  }.merge(args)
71
72
 
72
73
  self.vote_registered = false
@@ -76,22 +77,20 @@ module ActsAsVotable
76
77
  end
77
78
 
78
79
  # find the vote
79
- _votes_ = find_votes_for({
80
- :voter_id => options[:voter].id,
81
- :vote_scope => options[:vote_scope],
82
- :voter_type => options[:voter].class.base_class.name
83
- })
80
+ votes = find_votes_for(voter_id: options[:voter].id,
81
+ vote_scope: options[:vote_scope],
82
+ voter_type: options[:voter].class.base_class.name)
84
83
 
85
- if _votes_.count == 0 or options[:duplicate]
84
+ if votes.count == (0) || options[:duplicate]
86
85
  # this voter has never voted
87
86
  vote = ActsAsVotable::Vote.new(
88
- :votable => self,
89
- :voter => options[:voter],
90
- :vote_scope => options[:vote_scope]
87
+ votable: self,
88
+ voter: options[:voter],
89
+ vote_scope: options[:vote_scope]
91
90
  )
92
91
  else
93
92
  # this voter is potentially changing his vote
94
- vote = _votes_.last
93
+ vote = votes.last
95
94
  end
96
95
 
97
96
  last_update = vote.updated_at
@@ -109,192 +108,56 @@ module ActsAsVotable
109
108
  self.vote_registered = false
110
109
  return false
111
110
  end
112
-
113
111
  end
114
112
 
115
- def unvote args = {}
113
+ def unvote(args = {})
116
114
  return false if args[:voter].nil?
117
- _votes_ = find_votes_for(:voter_id => args[:voter].id, :vote_scope => args[:vote_scope], :voter_type => args[:voter].class.base_class.name)
115
+ votes = find_votes_for(voter_id: args[:voter].id, vote_scope: args[:vote_scope], voter_type: args[:voter].class.base_class.name)
118
116
 
119
- return true if _votes_.size == 0
120
- _votes_.each(&:destroy)
117
+ return true if votes.size == 0
118
+ votes.each(&:destroy)
121
119
  update_cached_votes args[:vote_scope]
122
120
  self.vote_registered = false if votes_for.count == 0
123
121
  return true
124
122
  end
125
123
 
126
- def vote_up voter, options={}
127
- self.vote_by :voter => voter, :vote => true, :vote_scope => options[:vote_scope], :vote_weight => options[:vote_weight]
128
- end
129
-
130
- def vote_down voter, options={}
131
- self.vote_by :voter => voter, :vote => false, :vote_scope => options[:vote_scope], :vote_weight => options[:vote_weight]
124
+ def vote_up(voter, options = {})
125
+ self.vote_by voter: voter, vote: true, vote_scope: options[:vote_scope], vote_weight: options[:vote_weight]
132
126
  end
133
127
 
134
- def unvote_by voter, options = {}
135
- self.unvote :voter => voter, :vote_scope => options[:vote_scope] #Does not need vote_weight since the votes_for are anyway getting destroyed
128
+ def vote_down(voter, options = {})
129
+ self.vote_by voter: voter, vote: false, vote_scope: options[:vote_scope], vote_weight: options[:vote_weight]
136
130
  end
137
131
 
138
- def scope_cache_field field, vote_scope
139
- return field if vote_scope.nil?
140
-
141
- case field
142
- when :cached_votes_total=
143
- "cached_scoped_#{vote_scope}_votes_total="
144
- when :cached_votes_total
145
- "cached_scoped_#{vote_scope}_votes_total"
146
- when :cached_votes_up=
147
- "cached_scoped_#{vote_scope}_votes_up="
148
- when :cached_votes_up
149
- "cached_scoped_#{vote_scope}_votes_up"
150
- when :cached_votes_down=
151
- "cached_scoped_#{vote_scope}_votes_down="
152
- when :cached_votes_down
153
- "cached_scoped_#{vote_scope}_votes_down"
154
- when :cached_votes_score=
155
- "cached_scoped_#{vote_scope}_votes_score="
156
- when :cached_votes_score
157
- "cached_scoped_#{vote_scope}_votes_score"
158
- when :cached_weighted_total
159
- "cached_weighted_#{vote_scope}_total"
160
- when :cached_weighted_total=
161
- "cached_weighted_#{vote_scope}_total="
162
- when :cached_weighted_score
163
- "cached_weighted_#{vote_scope}_score"
164
- when :cached_weighted_score=
165
- "cached_weighted_#{vote_scope}_score="
166
- end
167
- end
168
-
169
- # caching
170
- def update_cached_votes vote_scope = nil
171
-
172
- updates = {}
173
-
174
- if self.respond_to?(:cached_votes_total=)
175
- updates[:cached_votes_total] = count_votes_total(true)
176
- end
177
-
178
- if self.respond_to?(:cached_votes_up=)
179
- updates[:cached_votes_up] = count_votes_up(true)
180
- end
181
-
182
- if self.respond_to?(:cached_votes_down=)
183
- updates[:cached_votes_down] = count_votes_down(true)
184
- end
185
-
186
- if self.respond_to?(:cached_votes_score=)
187
- updates[:cached_votes_score] = (
188
- (updates[:cached_votes_up] || count_votes_up(true)) -
189
- (updates[:cached_votes_down] || count_votes_down(true))
190
- )
191
- end
192
-
193
- if self.respond_to?(:cached_weighted_total=)
194
- updates[:cached_weighted_total] = weighted_total(true)
195
- end
196
-
197
- if self.respond_to?(:cached_weighted_score=)
198
- updates[:cached_weighted_score] = weighted_score(true)
199
- end
200
-
201
- if vote_scope
202
- if self.respond_to?(scope_cache_field :cached_votes_total=, vote_scope)
203
- updates[scope_cache_field :cached_votes_total, vote_scope] = count_votes_total(true, vote_scope)
204
- end
205
-
206
- if self.respond_to?(scope_cache_field :cached_votes_up=, vote_scope)
207
- updates[scope_cache_field :cached_votes_up, vote_scope] = count_votes_up(true, vote_scope)
208
- end
209
-
210
- if self.respond_to?(scope_cache_field :cached_votes_down=, vote_scope)
211
- updates[scope_cache_field :cached_votes_down, vote_scope] = count_votes_down(true, vote_scope)
212
- end
213
-
214
- if self.respond_to?(scope_cache_field :cached_weighted_total=, vote_scope)
215
- updates[scope_cache_field :cached_weighted_total, vote_scope] = weighted_total(true, vote_scope)
216
- end
217
-
218
- if self.respond_to?(scope_cache_field :cached_weighted_score=, vote_scope)
219
- updates[scope_cache_field :cached_weighted_score, vote_scope] = weighted_score(true, vote_scope)
220
- end
221
-
222
- if self.respond_to?(scope_cache_field :cached_votes_score=, vote_scope)
223
- updates[scope_cache_field :cached_votes_score, vote_scope] = (
224
- (updates[scope_cache_field :cached_votes_up, vote_scope] || count_votes_up(true, vote_scope)) -
225
- (updates[scope_cache_field :cached_votes_down, vote_scope] || count_votes_down(true, vote_scope))
226
- )
227
- end
228
- end
229
-
230
- if (::ActiveRecord::VERSION::MAJOR == 3) && (::ActiveRecord::VERSION::MINOR != 0)
231
- self.update_attributes(updates, :without_protection => true) if updates.size > 0
232
- else
233
- self.update_attributes(updates) if updates.size > 0
234
- end
235
-
132
+ def unvote_by(voter, options = {})
133
+ self.unvote voter: voter, vote_scope: options[:vote_scope] #Does not need vote_weight since the votes_for are anyway getting destroyed
236
134
  end
237
135
 
238
-
239
136
  # results
240
- def find_votes_for extra_conditions = {}
137
+ def find_votes_for(extra_conditions = {})
241
138
  votes_for.where(extra_conditions)
242
139
  end
243
140
 
244
- def get_up_votes options={}
245
- find_votes_for(:vote_flag => true, :vote_scope => options[:vote_scope])
246
- end
247
-
248
- def get_down_votes options={}
249
- find_votes_for(:vote_flag => false, :vote_scope => options[:vote_scope])
250
- end
251
-
252
-
253
- # counting
254
- def count_votes_total skip_cache = false, vote_scope = nil
255
- if !skip_cache && self.respond_to?(scope_cache_field :cached_votes_total, vote_scope)
256
- return self.send(scope_cache_field :cached_votes_total, vote_scope)
257
- end
258
- find_votes_for(:vote_scope => vote_scope).count
259
- end
260
-
261
- def count_votes_up skip_cache = false, vote_scope = nil
262
- if !skip_cache && self.respond_to?(scope_cache_field :cached_votes_up, vote_scope)
263
- return self.send(scope_cache_field :cached_votes_up, vote_scope)
264
- end
265
- get_up_votes(:vote_scope => vote_scope).count
141
+ def get_up_votes(options = {})
142
+ vote_scope_hash = scope_or_empty_hash(options[:vote_scope])
143
+ find_votes_for({ vote_flag: true }.merge(vote_scope_hash))
266
144
  end
267
145
 
268
- def count_votes_down skip_cache = false, vote_scope = nil
269
- if !skip_cache && self.respond_to?(scope_cache_field :cached_votes_down, vote_scope)
270
- return self.send(scope_cache_field :cached_votes_down, vote_scope)
271
- end
272
- get_down_votes(:vote_scope => vote_scope).count
273
- end
274
-
275
- def weighted_total skip_cache = false, vote_scope = nil
276
- if !skip_cache && self.respond_to?(scope_cache_field :cached_weighted_total, vote_scope)
277
- return self.send(scope_cache_field :cached_weighted_total, vote_scope)
278
- end
279
- ups = get_up_votes(:vote_scope => vote_scope).sum(:vote_weight)
280
- downs = get_down_votes(:vote_scope => vote_scope).sum(:vote_weight)
281
- ups + downs
282
- end
283
-
284
- def weighted_score skip_cache = false, vote_scope = nil
285
- if !skip_cache && self.respond_to?(scope_cache_field :cached_weighted_score, vote_scope)
286
- return self.send(scope_cache_field :cached_weighted_score, vote_scope)
287
- end
288
- ups = get_up_votes(:vote_scope => vote_scope).sum(:vote_weight)
289
- downs = get_down_votes(:vote_scope => vote_scope).sum(:vote_weight)
290
- ups - downs
146
+ def get_down_votes(options = {})
147
+ vote_scope_hash = scope_or_empty_hash(options[:vote_scope])
148
+ find_votes_for({ vote_flag: false }.merge(vote_scope_hash))
291
149
  end
292
150
 
293
151
  # voters
294
- def voted_on_by? voter
295
- votes = find_votes_for :voter_id => voter.id, :voter_type => voter.class.base_class.name
152
+ def voted_on_by?(voter)
153
+ votes = find_votes_for voter_id: voter.id, voter_type: voter.class.base_class.name
296
154
  votes.count > 0
297
155
  end
298
156
 
157
+ private
158
+
159
+ def scope_or_empty_hash(vote_scope)
160
+ vote_scope ? { vote_scope: vote_scope } : {}
161
+ end
299
162
  end
300
163
  end