From d31e8f8fe4ba99e3e8e2ad15be1397d2f435dd37 Mon Sep 17 00:00:00 2001 From: Luke Baker Date: Thu, 16 Feb 2012 15:09:27 -0500 Subject: [PATCH] add vote_rate call --- CHANGELOG.md | 2 ++ app/controllers/questions_controller.rb | 9 +++++++++ app/models/question.rb | 13 +++++++++++++ config/routes.rb | 1 + spec/factories.rb | 12 +++++++++++- spec/integration/questions_spec.rb | 25 +++++++++++++++++++++++++ spec/models/question_spec.rb | 45 +++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 106 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff1bd34..d5ed9f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ + * Added vote_rate call to API + ## Pairwise 3.0.0 (Feb 10, 2012) ### * Upgrade to Rails 2.3.14 diff --git a/app/controllers/questions_controller.rb b/app/controllers/questions_controller.rb index 66b3b82..707a963 100644 --- a/app/controllers/questions_controller.rb +++ b/app/controllers/questions_controller.rb @@ -206,6 +206,15 @@ class QuestionsController < InheritedResources::Base end end + def vote_rate + @question = current_user.questions.find(params[:id]) + response = {:voterate => @question.vote_rate} + logger.info(@question.inspect) + respond_to do |format| + format.xml { render :xml => response.to_xml and return} + end + end + def object_info_totals_by_date object_type = params[:object_type] diff --git a/app/models/question.rb b/app/models/question.rb index 64599f5..29feeb4 100644 --- a/app/models/question.rb +++ b/app/models/question.rb @@ -672,6 +672,19 @@ class Question < ActiveRecord::Base last_appearance end + def vote_rate + return 0.to_f if total_uniq_sessions == 0 + sessions_with_vote.to_f / total_uniq_sessions.to_f + end + + def total_uniq_sessions + appearances.count(:select => "DISTINCT(voter_id)") + end + def sessions_with_vote + Question.connection.select_one(" + 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} + ").values.first + end end diff --git a/config/routes.rb b/config/routes.rb index 1a378e1..c4d88b0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -7,6 +7,7 @@ ActionController::Routing::Routes.draw do |map| :member => {:object_info_totals_by_date => :get, :object_info_by_visitor_id => :get, :median_votes_per_session => :get, + :vote_rate => :get, :export => :post} , :collection => {:all_num_votes_by_visitor_id => :get, :all_object_info_totals_by_date => :get, diff --git a/spec/factories.rb b/spec/factories.rb index 36f8054..9604dd7 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -67,21 +67,31 @@ Factory.define(:vote) do |f| f.choice {|v| v.prompt.left_choice} f.loser_choice {|v| v.prompt.right_choice} f.voter {|v| v.question.creator} + f.appearance { |v| Factory.build(:appearance, :voter => v.voter, :question => v.question) } +end + +Factory.define(:vote_new_user, :parent => :vote) do |f| + f.voter {|v| Factory.build(:visitor, :site => v.question.site)} end Factory.define(:skip) do |f| f.association :question, :factory => :aoi_question + f.appearance { |v| Factory.build(:appearance, :question => v.question) } f.prompt {|s| s.question.prompts.first} f.skipper {|s| s.question.creator} end Factory.define(:appearance) do |f| f.association :question, :factory => :aoi_question - f.prompt {|a| a.question.prompts.rand} + f.prompt {|a| a.question.prompts.sample} f.voter {|a| a.question.creator} f.answerable { nil } end +Factory.define(:appearance_new_user, :parent => :appearance) do |f| + f.voter {|a| Factory.build(:visitor, :site => a.question.site)} +end + Factory.sequence :email do |n| "user#{n}@example.com" end diff --git a/spec/integration/questions_spec.rb b/spec/integration/questions_spec.rb index 68aebe3..305f203 100644 --- a/spec/integration/questions_spec.rb +++ b/spec/integration/questions_spec.rb @@ -2,6 +2,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe "Questions" do include IntegrationSupport + include DBSupport before do @user = self.default_user = Factory(:email_confirmed_user) @choices = {} @@ -251,4 +252,28 @@ describe "Questions" do describe "GET 'object_info_totals_by_date'" do end + describe "GET 'vote_rate'" do + before(:all) { truncate_all } + it "should return the proper vote rate one vote" do + Factory.create(:vote, :question => @questions.first) + get_auth vote_rate_question_path(@questions.first, :format => 'xml') + response.should be_success + response.body.should have_tag("voterate", :text => "1.0") + end + it "should return the proper vote rate if 1 vote and 3 non-vote" do + Factory.create(:vote, :question => @questions.first) + 3.times do + Factory.create(:appearance_new_user, :question => @questions.first) + end + get_auth vote_rate_question_path(@questions.first, :format => 'xml') + response.should be_success + response.body.should have_tag("voterate", :text => "0.25") + end + it "should return the proper vote rate if no votes" do + get_auth vote_rate_question_path(@questions.first, :format => 'xml') + response.should be_success + response.body.should have_tag("voterate", :text => "0.0") + end + end + end diff --git a/spec/models/question_spec.rb b/spec/models/question_spec.rb index 1b95bcf..ed75649 100644 --- a/spec/models/question_spec.rb +++ b/spec/models/question_spec.rb @@ -248,6 +248,51 @@ describe Question do endTime = Time.now (endTime - start).should < 20 end + + context "vote rate" do + before(:all) do + truncate_all + @q = Factory.create(:aoi_question) + end + + it "should give proper stats required for vote rate" do + @q.total_uniq_sessions.should == 0 + @q.sessions_with_vote.should == 0 + @q.vote_rate.should == 0.0 + + # add new session + appearance, but no vote + Factory.create(:appearance_new_user, :question => @q) + @q.total_uniq_sessions.should == 1 + @q.sessions_with_vote.should == 0 + @q.vote_rate.should == 0.0 + + # add new vote + session + Factory.create(:vote, :question => @q) + Factory.create(:vote, :question => @q) + Factory.create(:vote, :question => @q) + @q.total_uniq_sessions.should == 2 + @q.sessions_with_vote.should == 1 + @q.vote_rate.should == 0.5 + + # add new session + appearance, but no vote + Factory.create(:appearance_new_user, :question => @q) + @q.total_uniq_sessions.should == 3 + @q.sessions_with_vote.should == 1 + @q.vote_rate.should == (1.to_f / 3.to_f) + + # add new session + appearance, but no vote + Factory.create(:appearance_new_user, :question => @q) + @q.total_uniq_sessions.should == 4 + @q.sessions_with_vote.should == 1 + @q.vote_rate.should == 0.25 + + # add new vote + session + v = Factory.create(:vote_new_user, :question => @q) + @q.total_uniq_sessions.should == 5 + @q.sessions_with_vote.should == 2 + @q.vote_rate.should == 0.4 + end + end context "catchup algorithm" do before(:all) do @catchup_q = Factory.create(:aoi_question) -- libgit2 0.21.2