Commit 14a2322e4f3dc7cca62c6edb4acae91c8269f3ec
1 parent
b36bc6f7
Exists in
master
and in
1 other branch
add votes per uploaded choice API call
Showing
7 changed files
with
79 additions
and
4 deletions
Show diff stats
CHANGELOG.md
1 | + * Added votes_per_uploaded_choice call to API | ||
1 | * Added median_responses_per_session call to API | 2 | * Added median_responses_per_session call to API |
2 | * Added upload_to_participation_ratio call to API | 3 | * Added upload_to_participation_ratio call to API |
3 | * Added vote_rate call to API | 4 | * Added vote_rate call to API |
app/controllers/questions_controller.rb
@@ -98,6 +98,14 @@ class QuestionsController < InheritedResources::Base | @@ -98,6 +98,14 @@ class QuestionsController < InheritedResources::Base | ||
98 | end | 98 | end |
99 | end | 99 | end |
100 | 100 | ||
101 | + def votes_per_uploaded_choice | ||
102 | + @question = current_user.questions.find(params[:id]) | ||
103 | + only_active = params[:only_active] == 'true' | ||
104 | + respond_to do |format| | ||
105 | + format.xml{ render :xml => {:value => @question.votes_per_uploaded_choice(only_active)}.to_xml and return} | ||
106 | + end | ||
107 | + end | ||
108 | + | ||
101 | def object_info_by_visitor_id | 109 | def object_info_by_visitor_id |
102 | 110 | ||
103 | object_type = params[:object_type] | 111 | object_type = params[:object_type] |
app/models/choice.rb
@@ -21,6 +21,9 @@ class Choice < ActiveRecord::Base | @@ -21,6 +21,9 @@ class Choice < ActiveRecord::Base | ||
21 | has_many :skips_on_the_right, :through => :prompts_on_the_right, :source => :skips | 21 | has_many :skips_on_the_right, :through => :prompts_on_the_right, :source => :skips |
22 | named_scope :active, :conditions => { :active => true } | 22 | named_scope :active, :conditions => { :active => true } |
23 | named_scope :inactive, :conditions => { :active => false} | 23 | named_scope :inactive, :conditions => { :active => false} |
24 | + named_scope :not_created_by, lambda { |creator_id| | ||
25 | + { :conditions => ["creator_id <> ?", creator_id] } | ||
26 | + } | ||
24 | 27 | ||
25 | after_save :update_questions_counter | 28 | after_save :update_questions_counter |
26 | after_save :update_prompt_queue | 29 | after_save :update_prompt_queue |
app/models/question.rb
@@ -672,6 +672,16 @@ class Question < ActiveRecord::Base | @@ -672,6 +672,16 @@ class Question < ActiveRecord::Base | ||
672 | last_appearance | 672 | last_appearance |
673 | end | 673 | end |
674 | 674 | ||
675 | + def votes_per_uploaded_choice(only_active=false) | ||
676 | + if only_active | ||
677 | + uploaded_choices_count = choices.active.not_created_by(creator_id).count | ||
678 | + else | ||
679 | + uploaded_choices_count = choices.not_created_by(creator_id).count | ||
680 | + end | ||
681 | + return 0.to_f if uploaded_choices_count == 0 | ||
682 | + votes.count.to_f / uploaded_choices_count.to_f | ||
683 | + end | ||
684 | + | ||
675 | # a response is either a vote or a skip, get the median per session | 685 | # a response is either a vote or a skip, get the median per session |
676 | def median_responses_per_session | 686 | def median_responses_per_session |
677 | median(Question.connection.select_values(" | 687 | median(Question.connection.select_values(" |
config/routes.rb
@@ -9,6 +9,7 @@ ActionController::Routing::Routes.draw do |map| | @@ -9,6 +9,7 @@ ActionController::Routing::Routes.draw do |map| | ||
9 | :median_votes_per_session => :get, | 9 | :median_votes_per_session => :get, |
10 | :vote_rate => :get, | 10 | :vote_rate => :get, |
11 | :median_responses_per_session => :get, | 11 | :median_responses_per_session => :get, |
12 | + :votes_per_uploaded_choice => :get, | ||
12 | :upload_to_participation_ratio => :get, | 13 | :upload_to_participation_ratio => :get, |
13 | :export => :post} , | 14 | :export => :post} , |
14 | :collection => {:all_num_votes_by_visitor_id => :get, | 15 | :collection => {:all_num_votes_by_visitor_id => :get, |
spec/integration/questions_spec.rb
@@ -252,6 +252,32 @@ describe "Questions" do | @@ -252,6 +252,32 @@ describe "Questions" do | ||
252 | describe "GET 'object_info_totals_by_date'" do | 252 | describe "GET 'object_info_totals_by_date'" do |
253 | end | 253 | end |
254 | 254 | ||
255 | + describe "GET 'votes_per_uploaded_choice'" do | ||
256 | + before(:all) { truncate_all } | ||
257 | + it "should return the proper value" do | ||
258 | + q = Factory.create(:aoi_question, :site => @api_user) | ||
259 | + get_auth votes_per_uploaded_choice_question_path(q, :format => 'xml') | ||
260 | + response.should be_success | ||
261 | + response.body.should have_tag("value", :text => "0.0") | ||
262 | + | ||
263 | + get_auth votes_per_uploaded_choice_question_path(q, :format => 'xml', :only_active => true) | ||
264 | + response.should be_success | ||
265 | + response.body.should have_tag("value", :text => "0.0") | ||
266 | + | ||
267 | + v = Factory.create(:vote_new_user, :question => q) | ||
268 | + Factory.create(:choice, :creator => v.voter, :question => q) | ||
269 | + Factory.create(:choice, :creator => v.voter, :question => q, :active => true) | ||
270 | + 4.times { Factory.create(:vote, :question => q, :voter => v.voter) } | ||
271 | + get_auth votes_per_uploaded_choice_question_path(q, :format => 'xml') | ||
272 | + response.should be_success | ||
273 | + response.body.should have_tag("value", :text => "2.5") | ||
274 | + | ||
275 | + get_auth votes_per_uploaded_choice_question_path(q, :format => 'xml', :only_active => true) | ||
276 | + response.should be_success | ||
277 | + response.body.should have_tag("value", :text => "5.0") | ||
278 | + end | ||
279 | + end | ||
280 | + | ||
255 | describe "GET 'median_responses_per_session'" do | 281 | describe "GET 'median_responses_per_session'" do |
256 | before(:all) { truncate_all } | 282 | before(:all) { truncate_all } |
257 | it "should return the median responses per session" do | 283 | it "should return the median responses per session" do |
spec/models/question_spec.rb
@@ -249,17 +249,17 @@ describe Question do | @@ -249,17 +249,17 @@ describe Question do | ||
249 | (endTime - start).should < 20 | 249 | (endTime - start).should < 20 |
250 | end | 250 | end |
251 | 251 | ||
252 | - context "ratio of uploaded ideas to participation" do | 252 | + context "median response per session" do |
253 | before(:all) do | 253 | before(:all) do |
254 | truncate_all | 254 | truncate_all |
255 | @q = Factory.create(:aoi_question) | 255 | @q = Factory.create(:aoi_question) |
256 | end | 256 | end |
257 | 257 | ||
258 | - it "should properly calculate median_responses_per_session with no responses" do | 258 | + it "should properly calculate with no responses" do |
259 | @q.median_responses_per_session.should == 0 | 259 | @q.median_responses_per_session.should == 0 |
260 | end | 260 | end |
261 | 261 | ||
262 | - it "should properly calculate median_responses_per_session with 2 sessions" do | 262 | + it "should properly calculate with 2 sessions" do |
263 | # one session with 1 vote, one with 2 votes | 263 | # one session with 1 vote, one with 2 votes |
264 | Factory.create(:vote_new_user, :question => @q) | 264 | Factory.create(:vote_new_user, :question => @q) |
265 | v = Factory.create(:vote_new_user, :question => @q) | 265 | v = Factory.create(:vote_new_user, :question => @q) |
@@ -267,7 +267,7 @@ describe Question do | @@ -267,7 +267,7 @@ describe Question do | ||
267 | @q.median_responses_per_session.should == 1.5 | 267 | @q.median_responses_per_session.should == 1.5 |
268 | end | 268 | end |
269 | 269 | ||
270 | - it "should properly calculate median_responses_per_session with 3 sessions" do | 270 | + it "should properly calculate with 3 sessions" do |
271 | # one session with 3 skips, 2 votes | 271 | # one session with 3 skips, 2 votes |
272 | v = Factory.create(:vote_new_user, :question => @q) | 272 | v = Factory.create(:vote_new_user, :question => @q) |
273 | 3.times { Factory.create(:skip, :question => @q, :skipper => v.voter) } | 273 | 3.times { Factory.create(:skip, :question => @q, :skipper => v.voter) } |
@@ -283,7 +283,33 @@ describe Question do | @@ -283,7 +283,33 @@ describe Question do | ||
283 | 4.times { Factory.create(:vote, :question => @q, :voter => v.voter) } | 283 | 4.times { Factory.create(:vote, :question => @q, :voter => v.voter) } |
284 | @q.median_responses_per_session.should == 5 | 284 | @q.median_responses_per_session.should == 5 |
285 | end | 285 | end |
286 | + end | ||
287 | + | ||
288 | + context "votes per uploaded choice" do | ||
289 | + before(:all) do | ||
290 | + truncate_all | ||
291 | + @q = Factory.create(:aoi_question) | ||
292 | + end | ||
293 | + it "should be calculated properly with no uploaded choices" do | ||
294 | + @q.votes_per_uploaded_choice.should == 0.0 | ||
295 | + @q.votes_per_uploaded_choice(true).should == 0.0 | ||
296 | + end | ||
297 | + | ||
298 | + it "should be calculated properly with some choices and votes" do | ||
299 | + v = Factory.create(:vote_new_user, :question => @q) | ||
300 | + Factory.create(:choice, :creator => v.voter, :question => @q) | ||
301 | + Factory.create(:choice, :creator => v.voter, :question => @q, :active => true) | ||
302 | + 4.times { Factory.create(:vote, :question => @q, :voter => v.voter) } | ||
303 | + @q.votes_per_uploaded_choice.should == 2.5 | ||
304 | + @q.votes_per_uploaded_choice(true).should == 5.0 | ||
305 | + end | ||
306 | + end | ||
286 | 307 | ||
308 | + context "ratio of uploaded ideas to participation" do | ||
309 | + before(:all) do | ||
310 | + truncate_all | ||
311 | + @q = Factory.create(:aoi_question) | ||
312 | + end | ||
287 | it "should give proper stats required for idea:participation ratio" do | 313 | it "should give proper stats required for idea:participation ratio" do |
288 | @q.sessions_with_uploaded_ideas.should == 0 | 314 | @q.sessions_with_uploaded_ideas.should == 0 |
289 | @q.sessions_with_participation.should == 0 | 315 | @q.sessions_with_participation.should == 0 |