Commit 51e3a6930d27d7f06c32244b197895dff4151b0e

Authored by Dhruv Kapadia
1 parent d0820545

Handle updating counter cache values when invalid flag is used

app/models/vote.rb
@@ -23,6 +23,7 @@ class Vote < ActiveRecord::Base @@ -23,6 +23,7 @@ class Vote < ActiveRecord::Base
23 serialize :tracking 23 serialize :tracking
24 24
25 after_create :update_winner_choice, :update_loser_choice 25 after_create :update_winner_choice, :update_loser_choice
  26 + after_save :update_counter_caches_based_on_flags
26 27
27 def update_winner_choice 28 def update_winner_choice
28 choice.reload # make sure we're using updated counter values 29 choice.reload # make sure we're using updated counter values
@@ -33,4 +34,22 @@ class Vote < ActiveRecord::Base @@ -33,4 +34,22 @@ class Vote < ActiveRecord::Base
33 loser_choice.reload 34 loser_choice.reload
34 loser_choice.compute_score! 35 loser_choice.compute_score!
35 end 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 end 55 end
spec/models/visitor_spec.rb
@@ -126,6 +126,7 @@ describe Visitor do @@ -126,6 +126,7 @@ describe Visitor do
126 126
127 valid_skip = @visitor.skip!(allparams) 127 valid_skip = @visitor.skip!(allparams)
128 @visitor.skips.count.should == 1 128 @visitor.skips.count.should == 1
  129 + @visitor.skips.size.should == 1
129 @appearance.reload.answerable.should == valid_skip 130 @appearance.reload.answerable.should == valid_skip
130 131
131 # we need to reset because vote_for deletes keys from the params 132 # we need to reset because vote_for deletes keys from the params
@@ -137,6 +138,7 @@ describe Visitor do @@ -137,6 +138,7 @@ describe Visitor do
137 invalid_skip.validity_information.should == "Appearance #{@appearance.id} already answered" 138 invalid_skip.validity_information.should == "Appearance #{@appearance.id} already answered"
138 @appearance.reload.answerable.should == valid_skip 139 @appearance.reload.answerable.should == valid_skip
139 @visitor.reload.skips.count.should == 1 140 @visitor.reload.skips.count.should == 1
  141 + @visitor.reload.skips.size.should == 1
140 end 142 end
141 143
142 it "should mark a vote as invalid if submitted with an already answered appearance" do 144 it "should mark a vote as invalid if submitted with an already answered appearance" do
@@ -146,6 +148,7 @@ describe Visitor do @@ -146,6 +148,7 @@ describe Visitor do
146 148
147 valid_vote = @visitor.vote_for!(allparams) 149 valid_vote = @visitor.vote_for!(allparams)
148 @visitor.votes.count.should == 1 150 @visitor.votes.count.should == 1
  151 + @question.reload.votes.size.should == 1
149 @appearance.reload.answerable.should == valid_vote 152 @appearance.reload.answerable.should == valid_vote
150 153
151 # we need to reset because vote_for deletes keys from the params 154 # we need to reset because vote_for deletes keys from the params
@@ -157,6 +160,7 @@ describe Visitor do @@ -157,6 +160,7 @@ describe Visitor do
157 invalid_vote.validity_information.should == "Appearance #{@appearance.id} already answered" 160 invalid_vote.validity_information.should == "Appearance #{@appearance.id} already answered"
158 @appearance.reload.answerable.should == valid_vote 161 @appearance.reload.answerable.should == valid_vote
159 @visitor.reload.votes.count.should == 1 162 @visitor.reload.votes.count.should == 1
  163 + @question.reload.votes.size.should == 1 #test counter cache works as well
160 end 164 end
161 165
162 it "should accurately update score counts after vote" do 166 it "should accurately update score counts after vote" do
spec/models/vote_spec.rb
@@ -11,6 +11,10 @@ describe Vote do @@ -11,6 +11,10 @@ describe Vote do
11 before(:each) do 11 before(:each) do
12 @question = Factory.create(:aoi_question) 12 @question = Factory.create(:aoi_question)
13 @prompt = @question.prompts.first 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 end 18 end
15 19
16 it "should create a new instance with factory girl" do 20 it "should create a new instance with factory girl" do
@@ -95,16 +99,89 @@ describe Vote do @@ -95,16 +99,89 @@ describe Vote do
95 end 99 end
96 100
97 it "should allow default valid_record behavior to be overriden by default" do 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 vote.valid_record.should be_true 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 vote.valid_record.should be_false 106 vote.valid_record.should be_false
109 end 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 end 187 end