acts_as_votable 0.10.0 → 0.11.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.
- checksums.yaml +4 -4
- data/.gitignore +9 -6
- data/.rubocop.yml +121 -0
- data/.travis.yml +12 -23
- data/Appraisals +13 -0
- data/Gemfile +3 -14
- data/README.markdown +80 -13
- data/Rakefile +6 -4
- data/acts_as_votable.gemspec +12 -5
- data/gemfiles/.bundle/config +2 -0
- data/gemfiles/rails_4.gemfile +7 -0
- data/gemfiles/rails_4.gemfile.lock +159 -0
- data/gemfiles/rails_5.gemfile +7 -0
- data/gemfiles/rails_5.gemfile.lock +166 -0
- data/gemfiles/rails_5_1.gemfile +7 -0
- data/gemfiles/rails_5_1.gemfile.lock +166 -0
- data/lib/acts_as_votable.rb +9 -9
- data/lib/acts_as_votable/cacheable.rb +174 -0
- data/lib/acts_as_votable/extenders/controller.rb +3 -4
- data/lib/acts_as_votable/extenders/votable.rb +17 -6
- data/lib/acts_as_votable/extenders/voter.rb +4 -6
- data/lib/acts_as_votable/helpers/words.rb +7 -10
- data/lib/acts_as_votable/version.rb +3 -1
- data/lib/acts_as_votable/votable.rb +50 -187
- data/lib/acts_as_votable/vote.rb +10 -12
- data/lib/acts_as_votable/voter.rb +52 -53
- data/lib/generators/acts_as_votable/migration/migration_generator.rb +19 -4
- data/lib/generators/acts_as_votable/migration/templates/active_record/{migration.rb → migration.erb} +1 -6
- data/spec/factories/votable.rb +6 -0
- data/spec/factories/votable_cache.rb +6 -0
- data/spec/factories/votable_cache_update_attributes.rb +6 -0
- data/spec/factories/votable_cache_update_columns.rb +6 -0
- data/spec/factories/votable_child_of_sti_not_votable.rb +6 -0
- data/spec/factories/votable_child_of_sti_votable.rb +6 -0
- data/spec/factories/votable_voter.rb +6 -0
- data/spec/factories/vote.rb +6 -0
- data/spec/factories/voter.rb +6 -0
- data/spec/generators/active_record_generator_spec.rb +13 -0
- data/spec/shared_example/votable_model.rb +506 -0
- data/spec/shared_example/voter_model.rb +280 -0
- data/spec/spec_helper.rb +28 -18
- data/spec/support/factory_girl.rb +10 -0
- data/spec/votable_spec.rb +10 -9
- data/spec/votable_voter_spec.rb +12 -12
- data/spec/voter_spec.rb +9 -10
- data/spec/words_spec.rb +9 -12
- metadata +98 -27
- data/spec/shared_example/votable_model_spec.rb +0 -421
- data/spec/shared_example/voter_model_spec.rb +0 -279
data/lib/acts_as_votable.rb
CHANGED
@@ -1,21 +1,21 @@
|
|
1
|
-
|
2
|
-
|
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
|
10
|
-
require
|
11
|
-
require
|
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
|
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
|
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(*
|
11
|
-
require
|
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
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
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
|
-
[
|
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
|
-
[
|
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
|
29
|
+
def self.meaning_of(word)
|
32
30
|
!that_mean_false.include?(word)
|
33
31
|
end
|
34
|
-
|
35
32
|
end
|
36
33
|
end
|
@@ -1,39 +1,41 @@
|
|
1
|
-
|
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
|
9
|
-
|
11
|
+
def self.included(base)
|
10
12
|
# allow the user to define these himself
|
11
13
|
aliases = {
|
12
14
|
|
13
|
-
:
|
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
|
-
:
|
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
|
-
:
|
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
|
-
:
|
29
|
+
get_down_votes: [
|
28
30
|
:get_false_votes, :get_downs, :get_downvotes, :get_dislikes, :get_negatives
|
29
31
|
],
|
30
|
-
:
|
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, :
|
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
|
-
:
|
60
|
-
:
|
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
|
66
|
-
|
67
|
+
def vote_by(args = {})
|
67
68
|
options = {
|
68
|
-
:
|
69
|
-
:
|
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
|
-
|
80
|
-
:
|
81
|
-
:
|
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
|
84
|
+
if votes.count == (0) || options[:duplicate]
|
86
85
|
# this voter has never voted
|
87
86
|
vote = ActsAsVotable::Vote.new(
|
88
|
-
:
|
89
|
-
:
|
90
|
-
:
|
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 =
|
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
|
113
|
+
def unvote(args = {})
|
116
114
|
return false if args[:voter].nil?
|
117
|
-
|
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
|
120
|
-
|
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
|
127
|
-
self.vote_by :
|
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
|
135
|
-
self.
|
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
|
139
|
-
|
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
|
137
|
+
def find_votes_for(extra_conditions = {})
|
241
138
|
votes_for.where(extra_conditions)
|
242
139
|
end
|
243
140
|
|
244
|
-
def get_up_votes
|
245
|
-
|
246
|
-
|
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
|
269
|
-
|
270
|
-
|
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?
|
295
|
-
votes = find_votes_for :
|
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
|