Skip to content

Commit

Permalink
add API call for median votes per session
Browse files Browse the repository at this point in the history
  • Loading branch information
lukebaker committed May 5, 2011
1 parent bfb34f2 commit 1a096cc
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 1 deletion.
7 changes: 7 additions & 0 deletions app/controllers/questions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ def export
# export_format = params[:export_format] #CSV always now, could expand to xml later
end

def median_votes_per_session
@question = current_user.questions.find(params[:id])
respond_to do |format|
format.xml{ render :xml => {:median => @question.median_votes_per_session}.to_xml and return}
end
end

def object_info_by_visitor_id

object_type = params[:object_type]
Expand Down
13 changes: 12 additions & 1 deletion app/models/question.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class Question < ActiveRecord::Base
require 'set'
include Utility
extend ActiveSupport::Memoizable

belongs_to :creator, :class_name => "Visitor", :foreign_key => "creator_id"
Expand Down Expand Up @@ -50,7 +51,17 @@ def create_choices_from_ideas
def item_count
choices.size
end


# returns array of hashes where each has has voter_id and total keys
def votes_per_session
self.votes.find(:all, :select => 'voter_id, count(*) as total', :group => :voter_id).map { |v| {:voter_id => v.voter_id, :total => v.total.to_i} }
end

def median_votes_per_session
totals = self.votes_per_session.map { |v| v[:total] }
return median(totals)
end

def choose_prompt(options = {})

# if there is one or fewer active choices, we won't be able to find a prompt
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
map.resources :questions, :except => [:edit, :destroy],
:member => {:object_info_totals_by_date => :get,
:object_info_by_visitor_id => :get,
:median_votes_per_session => :get,
:export => :post} ,
:collection => {:all_num_votes_by_visitor_id => :get,
:all_object_info_totals_by_date => :get,
Expand Down
12 changes: 12 additions & 0 deletions lib/utility.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module Utility
def mean(array)
array.inject(0) { |sum, x| sum += x } / array.size.to_f
end

def median(array, already_sorted=false)
return nil if array.empty?
array = array.sort unless already_sorted
m_pos = array.size / 2
return array.size % 2 == 1 ? array[m_pos] : mean(array[m_pos-1..m_pos])
end
end
9 changes: 9 additions & 0 deletions spec/integration/questions_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@
end
end

describe "GET 'median_votes_per_session'" do
it "should return the median" do
Factory.create(:vote, :question => @questions.first)
get_auth median_votes_per_session_question_path(@questions.first, :format => 'xml')
response.should be_success
response.body.should have_tag("median", :text => "1")
end
end

describe "GET 'index'" do
it "should return an array of questions" do
get_auth questions_path(:format => 'xml')
Expand Down
9 changes: 9 additions & 0 deletions spec/models/question_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@
@question.choices.active.reload.size.should == 2
end

it "should report median votes per session" do
aoiquestion = Factory.create(:aoi_question)
prompt = aoiquestion.prompts.first
Factory.create(:vote, :question => aoiquestion, :prompt => prompt)
Factory.create(:vote, :question => aoiquestion, :prompt => prompt)
aoiquestion.votes_per_session.should == [{:voter_id => aoiquestion.creator.id, :total => 2}]
aoiquestion.median_votes_per_session.should == 2
end

it "should create a new instance given valid attributes" do
# Factory.attributes_for does not return associations, this is a good enough substitute
Question.create!(Factory.build(:question).attributes.symbolize_keys)
Expand Down

0 comments on commit 1a096cc

Please sign in to comment.