From 14a2322e4f3dc7cca62c6edb4acae91c8269f3ec Mon Sep 17 00:00:00 2001 From: Luke Baker Date: Fri, 24 Feb 2012 12:54:14 -0500 Subject: [PATCH] add votes per uploaded choice API call --- CHANGELOG.md | 1 + app/controllers/questions_controller.rb | 8 ++++++++ app/models/choice.rb | 3 +++ app/models/question.rb | 10 ++++++++++ config/routes.rb | 1 + spec/integration/questions_spec.rb | 26 ++++++++++++++++++++++++++ spec/models/question_spec.rb | 34 ++++++++++++++++++++++++++++++---- 7 files changed, 79 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0059fe8..e43f3dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,4 @@ + * Added votes_per_uploaded_choice call to API * Added median_responses_per_session call to API * Added upload_to_participation_ratio call to API * Added vote_rate call to API diff --git a/app/controllers/questions_controller.rb b/app/controllers/questions_controller.rb index 27a549b..d2ee388 100644 --- a/app/controllers/questions_controller.rb +++ b/app/controllers/questions_controller.rb @@ -98,6 +98,14 @@ class QuestionsController < InheritedResources::Base end end + def votes_per_uploaded_choice + @question = current_user.questions.find(params[:id]) + only_active = params[:only_active] == 'true' + respond_to do |format| + format.xml{ render :xml => {:value => @question.votes_per_uploaded_choice(only_active)}.to_xml and return} + end + end + def object_info_by_visitor_id object_type = params[:object_type] diff --git a/app/models/choice.rb b/app/models/choice.rb index 2185f14..09b975a 100644 --- a/app/models/choice.rb +++ b/app/models/choice.rb @@ -21,6 +21,9 @@ class Choice < ActiveRecord::Base has_many :skips_on_the_right, :through => :prompts_on_the_right, :source => :skips named_scope :active, :conditions => { :active => true } named_scope :inactive, :conditions => { :active => false} + named_scope :not_created_by, lambda { |creator_id| + { :conditions => ["creator_id <> ?", creator_id] } + } after_save :update_questions_counter after_save :update_prompt_queue diff --git a/app/models/question.rb b/app/models/question.rb index 09c8dac..77d2933 100644 --- a/app/models/question.rb +++ b/app/models/question.rb @@ -672,6 +672,16 @@ class Question < ActiveRecord::Base last_appearance end + def votes_per_uploaded_choice(only_active=false) + if only_active + uploaded_choices_count = choices.active.not_created_by(creator_id).count + else + uploaded_choices_count = choices.not_created_by(creator_id).count + end + return 0.to_f if uploaded_choices_count == 0 + votes.count.to_f / uploaded_choices_count.to_f + end + # a response is either a vote or a skip, get the median per session def median_responses_per_session median(Question.connection.select_values(" diff --git a/config/routes.rb b/config/routes.rb index 6bed27b..fde3e18 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -9,6 +9,7 @@ ActionController::Routing::Routes.draw do |map| :median_votes_per_session => :get, :vote_rate => :get, :median_responses_per_session => :get, + :votes_per_uploaded_choice => :get, :upload_to_participation_ratio => :get, :export => :post} , :collection => {:all_num_votes_by_visitor_id => :get, diff --git a/spec/integration/questions_spec.rb b/spec/integration/questions_spec.rb index be778f3..d04d519 100644 --- a/spec/integration/questions_spec.rb +++ b/spec/integration/questions_spec.rb @@ -252,6 +252,32 @@ describe "Questions" do describe "GET 'object_info_totals_by_date'" do end + describe "GET 'votes_per_uploaded_choice'" do + before(:all) { truncate_all } + it "should return the proper value" do + q = Factory.create(:aoi_question, :site => @api_user) + get_auth votes_per_uploaded_choice_question_path(q, :format => 'xml') + response.should be_success + response.body.should have_tag("value", :text => "0.0") + + get_auth votes_per_uploaded_choice_question_path(q, :format => 'xml', :only_active => true) + response.should be_success + response.body.should have_tag("value", :text => "0.0") + + v = Factory.create(:vote_new_user, :question => q) + Factory.create(:choice, :creator => v.voter, :question => q) + Factory.create(:choice, :creator => v.voter, :question => q, :active => true) + 4.times { Factory.create(:vote, :question => q, :voter => v.voter) } + get_auth votes_per_uploaded_choice_question_path(q, :format => 'xml') + response.should be_success + response.body.should have_tag("value", :text => "2.5") + + get_auth votes_per_uploaded_choice_question_path(q, :format => 'xml', :only_active => true) + response.should be_success + response.body.should have_tag("value", :text => "5.0") + end + end + describe "GET 'median_responses_per_session'" do before(:all) { truncate_all } it "should return the median responses per session" do diff --git a/spec/models/question_spec.rb b/spec/models/question_spec.rb index 4b1cf22..e8e14c1 100644 --- a/spec/models/question_spec.rb +++ b/spec/models/question_spec.rb @@ -249,17 +249,17 @@ describe Question do (endTime - start).should < 20 end - context "ratio of uploaded ideas to participation" do + context "median response per session" do before(:all) do truncate_all @q = Factory.create(:aoi_question) end - it "should properly calculate median_responses_per_session with no responses" do + it "should properly calculate with no responses" do @q.median_responses_per_session.should == 0 end - it "should properly calculate median_responses_per_session with 2 sessions" do + it "should properly calculate with 2 sessions" do # one session with 1 vote, one with 2 votes Factory.create(:vote_new_user, :question => @q) v = Factory.create(:vote_new_user, :question => @q) @@ -267,7 +267,7 @@ describe Question do @q.median_responses_per_session.should == 1.5 end - it "should properly calculate median_responses_per_session with 3 sessions" do + it "should properly calculate with 3 sessions" do # one session with 3 skips, 2 votes v = Factory.create(:vote_new_user, :question => @q) 3.times { Factory.create(:skip, :question => @q, :skipper => v.voter) } @@ -283,7 +283,33 @@ describe Question do 4.times { Factory.create(:vote, :question => @q, :voter => v.voter) } @q.median_responses_per_session.should == 5 end + end + + context "votes per uploaded choice" do + before(:all) do + truncate_all + @q = Factory.create(:aoi_question) + end + it "should be calculated properly with no uploaded choices" do + @q.votes_per_uploaded_choice.should == 0.0 + @q.votes_per_uploaded_choice(true).should == 0.0 + end + + it "should be calculated properly with some choices and votes" do + v = Factory.create(:vote_new_user, :question => @q) + Factory.create(:choice, :creator => v.voter, :question => @q) + Factory.create(:choice, :creator => v.voter, :question => @q, :active => true) + 4.times { Factory.create(:vote, :question => @q, :voter => v.voter) } + @q.votes_per_uploaded_choice.should == 2.5 + @q.votes_per_uploaded_choice(true).should == 5.0 + end + end + context "ratio of uploaded ideas to participation" do + before(:all) do + truncate_all + @q = Factory.create(:aoi_question) + end it "should give proper stats required for idea:participation ratio" do @q.sessions_with_uploaded_ideas.should == 0 @q.sessions_with_participation.should == 0 -- libgit2 0.21.2