Commit 51e3a6930d27d7f06c32244b197895dff4151b0e
1 parent
d0820545
Exists in
master
and in
1 other branch
Handle updating counter cache values when invalid flag is used
Showing
3 changed files
with
108 additions
and
8 deletions
Show diff stats
app/models/vote.rb
... | ... | @@ -23,6 +23,7 @@ class Vote < ActiveRecord::Base |
23 | 23 | serialize :tracking |
24 | 24 | |
25 | 25 | after_create :update_winner_choice, :update_loser_choice |
26 | + after_save :update_counter_caches_based_on_flags | |
26 | 27 | |
27 | 28 | def update_winner_choice |
28 | 29 | choice.reload # make sure we're using updated counter values |
... | ... | @@ -33,4 +34,22 @@ class Vote < ActiveRecord::Base |
33 | 34 | loser_choice.reload |
34 | 35 | loser_choice.compute_score! |
35 | 36 | end |
37 | + | |
38 | + # this is necessary to handle counter cache, at least until the following patch is accepted: | |
39 | + # https://rails.lighthouseapp.com/projects/8994/tickets/3521-patch-add-conditional-counter-cache | |
40 | + def update_counter_caches_based_on_flags | |
41 | + if valid_record_changed? | |
42 | + if valid_record | |
43 | + Question.increment_counter(:votes_count, self.question_id) | |
44 | + Prompt.increment_counter(:votes_count, self.prompt_id) | |
45 | + Choice.increment_counter(:wins, self.choice_id) | |
46 | + Choice.increment_counter(:losses, self.loser_choice_id) | |
47 | + else | |
48 | + Question.decrement_counter(:votes_count, self.question_id) | |
49 | + Prompt.decrement_counter(:votes_count, self.prompt_id) | |
50 | + Choice.decrement_counter(:wins, self.choice_id) | |
51 | + Choice.decrement_counter(:losses, self.loser_choice_id) | |
52 | + end | |
53 | + end | |
54 | + end | |
36 | 55 | end | ... | ... |
spec/models/visitor_spec.rb
... | ... | @@ -126,6 +126,7 @@ describe Visitor do |
126 | 126 | |
127 | 127 | valid_skip = @visitor.skip!(allparams) |
128 | 128 | @visitor.skips.count.should == 1 |
129 | + @visitor.skips.size.should == 1 | |
129 | 130 | @appearance.reload.answerable.should == valid_skip |
130 | 131 | |
131 | 132 | # we need to reset because vote_for deletes keys from the params |
... | ... | @@ -137,6 +138,7 @@ describe Visitor do |
137 | 138 | invalid_skip.validity_information.should == "Appearance #{@appearance.id} already answered" |
138 | 139 | @appearance.reload.answerable.should == valid_skip |
139 | 140 | @visitor.reload.skips.count.should == 1 |
141 | + @visitor.reload.skips.size.should == 1 | |
140 | 142 | end |
141 | 143 | |
142 | 144 | it "should mark a vote as invalid if submitted with an already answered appearance" do |
... | ... | @@ -146,6 +148,7 @@ describe Visitor do |
146 | 148 | |
147 | 149 | valid_vote = @visitor.vote_for!(allparams) |
148 | 150 | @visitor.votes.count.should == 1 |
151 | + @question.reload.votes.size.should == 1 | |
149 | 152 | @appearance.reload.answerable.should == valid_vote |
150 | 153 | |
151 | 154 | # we need to reset because vote_for deletes keys from the params |
... | ... | @@ -157,6 +160,7 @@ describe Visitor do |
157 | 160 | invalid_vote.validity_information.should == "Appearance #{@appearance.id} already answered" |
158 | 161 | @appearance.reload.answerable.should == valid_vote |
159 | 162 | @visitor.reload.votes.count.should == 1 |
163 | + @question.reload.votes.size.should == 1 #test counter cache works as well | |
160 | 164 | end |
161 | 165 | |
162 | 166 | it "should accurately update score counts after vote" do | ... | ... |
spec/models/vote_spec.rb
... | ... | @@ -11,6 +11,10 @@ describe Vote do |
11 | 11 | before(:each) do |
12 | 12 | @question = Factory.create(:aoi_question) |
13 | 13 | @prompt = @question.prompts.first |
14 | + @required_params = {:question => @question, :prompt => @prompt, | |
15 | + :choice => @prompt.left_choice, | |
16 | + :voter=> @question.site.default_visitor, | |
17 | + :loser_choice => @prompt.right_choice} | |
14 | 18 | end |
15 | 19 | |
16 | 20 | it "should create a new instance with factory girl" do |
... | ... | @@ -95,16 +99,89 @@ describe Vote do |
95 | 99 | end |
96 | 100 | |
97 | 101 | it "should allow default valid_record behavior to be overriden by default" do |
98 | - required_params = {:question => @question, :prompt => @prompt, | |
99 | - :choice => @prompt.left_choice, | |
100 | - :voter=> @question.site.default_visitor, | |
101 | - :loser_choice => @prompt.right_choice} | |
102 | - | |
103 | - vote = Vote.create!(required_params) | |
102 | + vote = Vote.create!(@required_params) | |
104 | 103 | vote.valid_record.should be_true |
105 | 104 | |
106 | - | |
107 | - vote = Vote.create!(required_params.merge!(:valid_record => false)) | |
105 | + vote = Vote.create!(@required_params.merge!(:valid_record => false)) | |
108 | 106 | vote.valid_record.should be_false |
109 | 107 | end |
108 | + | |
109 | + it "should update counter cache on question when vote is flagged as invalid" do | |
110 | + vote = Factory.create(:vote, :question => @question) | |
111 | + @question.reload | |
112 | + @question.votes.size.should == 1 | |
113 | + @question.votes_count.should == 1 | |
114 | + | |
115 | + vote.valid_record = false; | |
116 | + vote.save | |
117 | + | |
118 | + @question.reload | |
119 | + @question.votes.size.should == 0 | |
120 | + @question.votes_count.should == 0 | |
121 | + | |
122 | + the_vote = Factory.create(:vote, :question => @question) | |
123 | + the_vote.validity_information = "blah blah blah" | |
124 | + the_vote.save | |
125 | + | |
126 | + @question.reload.votes.size.should == 1 | |
127 | + | |
128 | + end | |
129 | + it "should update counter cache on question when vote is created with invalid flag" do | |
130 | + vote = Vote.create!(@required_params) | |
131 | + @question.reload.votes.size.should == 1 | |
132 | + | |
133 | + vote = Vote.create!(@required_params.merge!(:valid_record => false)) | |
134 | + @question.reload.votes.size.should == 1 | |
135 | + end | |
136 | + | |
137 | + it "should update counter cache on choice after changing valid status" do | |
138 | + vote = Factory.create(:vote, :question => @question, :prompt => @prompt, | |
139 | + :choice => @prompt.left_choice) | |
140 | + | |
141 | + @prompt.left_choice.reload | |
142 | + @prompt.left_choice.votes.size.should == 1 | |
143 | + @prompt.left_choice.wins.should == 1 | |
144 | + | |
145 | + vote.valid_record = false | |
146 | + vote.save | |
147 | + @prompt.left_choice.reload | |
148 | + @prompt.left_choice.votes.size.should == 0 | |
149 | + @prompt.left_choice.wins.should == 0 | |
150 | + | |
151 | + end | |
152 | + it "should update counter cache on prompt after changing valid status" do | |
153 | + vote = Factory.create(:vote, :question => @question, :prompt => @prompt) | |
154 | + | |
155 | + @prompt.reload | |
156 | + @prompt.votes.size.should == 1 | |
157 | + @prompt.votes_count.should == 1 | |
158 | + | |
159 | + vote.valid_record = false | |
160 | + vote.save | |
161 | + @prompt.reload | |
162 | + @prompt.votes.size.should == 0 | |
163 | + @prompt.votes_count.should == 0 | |
164 | + | |
165 | + end | |
166 | + | |
167 | + it "should update counter cache on loser_choice after invalid is changed" do | |
168 | + vote = Factory.create(:vote, :question => @question, :prompt => @prompt, | |
169 | + :choice => @prompt.left_choice, | |
170 | + :loser_choice => @prompt.right_choice) | |
171 | + | |
172 | + @prompt.right_choice.reload | |
173 | + @prompt.right_choice.votes.size.should == 0 | |
174 | + @prompt.right_choice.wins.should == 0 | |
175 | + @prompt.right_choice.losses.should == 1 | |
176 | + | |
177 | + vote.valid_record = false | |
178 | + vote.save | |
179 | + | |
180 | + @prompt.right_choice.reload | |
181 | + @prompt.right_choice.votes.size.should == 0 | |
182 | + @prompt.right_choice.wins.should == 0 | |
183 | + @prompt.right_choice.losses.should == 0 | |
184 | + | |
185 | + end | |
186 | + | |
110 | 187 | end | ... | ... |