Commit b083c2c66fb39a0f670c9ebb9370edb3ca54445c

Authored by Luke Baker
1 parent d31e8f8f

added upload_to_participation_ratio

CHANGELOG.md
  1 + * Added upload_to_participation_ratio call to API
1 2 * Added vote_rate call to API
2 3  
3 4 ## Pairwise 3.0.0 (Feb 10, 2012) ###
... ...
app/controllers/questions_controller.rb
... ... @@ -209,9 +209,16 @@ class QuestionsController < InheritedResources::Base
209 209 def vote_rate
210 210 @question = current_user.questions.find(params[:id])
211 211 response = {:voterate => @question.vote_rate}
212   - logger.info(@question.inspect)
213 212 respond_to do |format|
214   - format.xml { render :xml => response.to_xml and return}
  213 + format.xml { render :xml => response.to_xml and return}
  214 + end
  215 + end
  216 +
  217 + def upload_to_participation_ratio
  218 + @question = current_user.questions.find(params[:id])
  219 + response = {:uploadparticipationratio => @question.upload_to_participation_ratio}
  220 + respond_to do |format|
  221 + format.xml { render :xml => response.to_xml and return}
215 222 end
216 223 end
217 224  
... ...
app/models/question.rb
... ... @@ -672,15 +672,44 @@ class Question < ActiveRecord::Base
672 672 last_appearance
673 673 end
674 674  
  675 + def upload_to_participation_ratio
  676 + swp = sessions_with_participation
  677 + return 0.to_f if swp == 0
  678 + sessions_with_uploaded_ideas.to_f / swp.to_f
  679 + end
  680 +
  681 + # total number of sessions that have uploaded an idea
  682 + def sessions_with_uploaded_ideas
  683 + choices.find(:all,
  684 + :conditions => ["creator_id <> ?", creator_id],
  685 + :group => :creator_id
  686 + ).count
  687 + end
  688 +
  689 + # total sessions with at least one vote, skip, or uploaded idea
  690 + def sessions_with_participation
  691 + Question.connection.select_one("
  692 + SELECT COUNT(*) FROM (
  693 + (SELECT DISTINCT(skipper_id) vid FROM skips WHERE question_id = #{id})
  694 + UNION
  695 + (SELECT DISTINCT(voter_id) vid FROM votes WHERE question_id = #{id} AND valid_record = 1)
  696 + UNION
  697 + (SELECT DISTINCT(creator_id) vid FROM choices WHERE question_id = #{id})
  698 + ) AS t WHERE vid <> #{creator_id}
  699 + ").values.first
  700 + end
  701 +
675 702 def vote_rate
676   - return 0.to_f if total_uniq_sessions == 0
677   - sessions_with_vote.to_f / total_uniq_sessions.to_f
  703 + tus = total_uniq_sessions
  704 + return 0.to_f if tus == 0
  705 + sessions_with_vote.to_f / tus.to_f
678 706 end
679 707  
680 708 def total_uniq_sessions
681 709 appearances.count(:select => "DISTINCT(voter_id)")
682 710 end
683 711  
  712 + # total number of sessions with at least one vote
684 713 def sessions_with_vote
685 714 Question.connection.select_one("
686 715 SELECT COUNT(DISTINCT(appearances.voter_id)) from appearances LEFT JOIN votes ON (votes.voter_id = appearances.voter_id) WHERE votes.id IS NOT NULL AND appearances.question_id = #{self.id}
... ...
config/routes.rb
... ... @@ -8,6 +8,7 @@ ActionController::Routing::Routes.draw do |map|
8 8 :object_info_by_visitor_id => :get,
9 9 :median_votes_per_session => :get,
10 10 :vote_rate => :get,
  11 + :upload_to_participation_ratio => :get,
11 12 :export => :post} ,
12 13 :collection => {:all_num_votes_by_visitor_id => :get,
13 14 :all_object_info_totals_by_date => :get,
... ...
spec/factories.rb
... ... @@ -61,6 +61,10 @@ Factory.define(:choice) do |f|
61 61 f.creator {|c| c.association(:visitor, :site => c.question.site)}
62 62 end
63 63  
  64 +Factory.define(:choice_new_user, :parent => :choice) do |f|
  65 + f.creator {|c| Factory.build(:visitor, :site => c.question.site)}
  66 +end
  67 +
64 68 Factory.define(:vote) do |f|
65 69 f.association :question, :factory => :aoi_question
66 70 f.prompt {|v| v.question.prompts.first}
... ... @@ -80,6 +84,9 @@ Factory.define(:skip) do |f|
80 84 f.prompt {|s| s.question.prompts.first}
81 85 f.skipper {|s| s.question.creator}
82 86 end
  87 +Factory.define(:skip_new_user, :parent => :skip) do |f|
  88 + f.skipper {|a| Factory.build(:visitor, :site => a.question.site)}
  89 +end
83 90  
84 91 Factory.define(:appearance) do |f|
85 92 f.association :question, :factory => :aoi_question
... ...
spec/integration/questions_spec.rb
... ... @@ -252,6 +252,38 @@ describe &quot;Questions&quot; do
252 252 describe "GET 'object_info_totals_by_date'" do
253 253 end
254 254  
  255 + describe "GET 'upload_to_participation_ratio'" do
  256 + before(:all) { truncate_all }
  257 + it "should return the proper upload:participation ratio" do
  258 + q = Factory.create(:aoi_question, :site => @api_user)
  259 + get_auth upload_to_participation_ratio_question_path(q, :format => 'xml')
  260 + response.should be_success
  261 + response.body.should have_tag("uploadparticipationratio", :text => "0.0")
  262 +
  263 + # 10 voting only sessions
  264 + 10.times { Factory.create(:vote_new_user, :question => q) }
  265 + # 7 users who voted and added ideas
  266 + 7.times do
  267 + v = Factory.create(:vote_new_user, :question => q)
  268 + Factory.create(:choice, :creator => v.voter, :question => q)
  269 + end
  270 + # 2 users who only skip
  271 + 2.times { Factory.create(:skip_new_user, :question => q) }
  272 + # 3 users who did everything
  273 + 3.times do
  274 + v = Factory.create(:vote_new_user, :question => q)
  275 + Factory.create(:choice, :creator => v.voter, :question => q)
  276 + Factory.create(:skip, :skipper => v.voter, :question => q)
  277 + end
  278 + # 5 users who only added ideas
  279 + 5.times { Factory.create(:choice_new_user, :question => q) }
  280 +
  281 + get_auth upload_to_participation_ratio_question_path(q, :format => 'xml')
  282 + response.should be_success
  283 + response.body.should have_tag("uploadparticipationratio", :text => "0.555555555555556")
  284 + end
  285 + end
  286 +
255 287 describe "GET 'vote_rate'" do
256 288 before(:all) { truncate_all }
257 289 it "should return the proper vote rate one vote" do
... ...
spec/models/question_spec.rb
... ... @@ -249,6 +249,57 @@ describe Question do
249 249 (endTime - start).should < 20
250 250 end
251 251  
  252 + context "ratio of uploaded ideas to participation" do
  253 + before(:all) do
  254 + truncate_all
  255 + @q = Factory.create(:aoi_question)
  256 + end
  257 +
  258 + it "should give proper stats required for idea:participation ratio" do
  259 + @q.sessions_with_uploaded_ideas.should == 0
  260 + @q.sessions_with_participation.should == 0
  261 + @q.upload_to_participation_ratio.should == 0.0
  262 +
  263 + # 10 voting only sessions
  264 + 10.times { Factory.create(:vote_new_user, :question => @q) }
  265 + @q.sessions_with_uploaded_ideas.should == 0
  266 + @q.sessions_with_participation.should == 10
  267 + @q.upload_to_participation_ratio.should == 0.0
  268 +
  269 + # 7 users who voted and added ideas
  270 + 7.times do
  271 + v = Factory.create(:vote_new_user, :question => @q)
  272 + Factory.create(:choice, :creator => v.voter, :question => @q)
  273 + end
  274 + @q.sessions_with_uploaded_ideas.should == 7
  275 + @q.sessions_with_participation.should == 17
  276 + @q.upload_to_participation_ratio.round(3).should == 0.412
  277 +
  278 + # 2 users who only skip
  279 + 2.times { Factory.create(:skip_new_user, :question => @q) }
  280 + @q.sessions_with_uploaded_ideas.should == 7
  281 + @q.sessions_with_participation.should == 19
  282 + @q.upload_to_participation_ratio.round(3).should == 0.368
  283 +
  284 + # 3 users who did everything
  285 + 3.times do
  286 + v = Factory.create(:vote_new_user, :question => @q)
  287 + Factory.create(:choice, :creator => v.voter, :question => @q)
  288 + Factory.create(:skip, :skipper => v.voter, :question => @q)
  289 + end
  290 + @q.sessions_with_uploaded_ideas.should == 10
  291 + @q.sessions_with_participation.should == 22
  292 + @q.upload_to_participation_ratio.round(3).should == 0.455
  293 +
  294 + # 5 users who only added ideas
  295 + 5.times { Factory.create(:choice_new_user, :question => @q) }
  296 + @q.sessions_with_uploaded_ideas.should == 15
  297 + @q.sessions_with_participation.should == 27
  298 + @q.upload_to_participation_ratio.round(3).should == 0.556
  299 +
  300 + end
  301 + end
  302 +
252 303 context "vote rate" do
253 304 before(:all) do
254 305 truncate_all
... ...