Commit 5fc443583add3894661117c188eadf0d71db2ced

Authored by Dmitri Garbuzov
2 parents 35d6ac47 dc8b6a29

Merge branch 'master' of http://github.com/allourideas/pairwise2

Conflicts:
	app/controllers/prompts_controller.rb
app/controllers/choices_controller.rb
@@ -12,8 +12,8 @@ class ChoicesController < InheritedResources::Base @@ -12,8 +12,8 @@ class ChoicesController < InheritedResources::Base
12 12
13 find_options = {:conditions => {:question_id => @question.id}, 13 find_options = {:conditions => {:question_id => @question.id},
14 :limit => params[:limit].to_i, 14 :limit => params[:limit].to_i,
15 - :order => 'score DESC',  
16 - :include => :item} 15 + :order => 'score DESC'
  16 + }
17 17
18 find_options[:conditions].merge!(:active => true) unless params[:include_inactive] 18 find_options[:conditions].merge!(:active => true) unless params[:include_inactive]
19 find_options.merge!(:offset => params[:offset]) if params[:offset] 19 find_options.merge!(:offset => params[:offset]) if params[:offset]
@@ -23,9 +23,9 @@ class ChoicesController < InheritedResources::Base @@ -23,9 +23,9 @@ class ChoicesController < InheritedResources::Base
23 else 23 else
24 @question = Question.find(params[:question_id], :include => :choices) #eagerloads ALL choices 24 @question = Question.find(params[:question_id], :include => :choices) #eagerloads ALL choices
25 unless params[:include_inactive] 25 unless params[:include_inactive]
26 - @choices = @question.choices(true).active.find(:all, :include => :item) 26 + @choices = @question.choices(true).active.find(:all)
27 else 27 else
28 - @choices = @question.choices.find(:all, :include =>:item) 28 + @choices = @question.choices.find(:all)
29 end 29 end
30 end 30 end
31 index! do |format| 31 index! do |format|
@@ -38,7 +38,7 @@ class ChoicesController < InheritedResources::Base @@ -38,7 +38,7 @@ class ChoicesController < InheritedResources::Base
38 show! do |format| 38 show! do |format|
39 format.xml { 39 format.xml {
40 @choice.reload 40 @choice.reload
41 - render :xml => @choice.to_xml(:methods => [:item_data, :wins_plus_losses, :question_name])} 41 + render :xml => @choice.to_xml(:methods => [:wins_plus_losses])}
42 format.json { render :json => @choice.to_json(:methods => [:data])} 42 format.json { render :json => @choice.to_json(:methods => [:data])}
43 end 43 end
44 end 44 end
app/controllers/items_controller.rb
@@ -1,86 +0,0 @@ @@ -1,86 +0,0 @@
1 -class ItemsController < ApplicationController  
2 - before_filter :authenticate  
3 - # GET /items  
4 - # GET /items.xml  
5 - def index  
6 - @items = Item.all  
7 -  
8 - respond_to do |format|  
9 - format.html # index.html.erb  
10 - format.xml { render :xml => @items }  
11 - end  
12 - end  
13 -  
14 - # GET /items/1  
15 - # GET /items/1.xml  
16 - def show  
17 - @item = Item.find(params[:id])  
18 -  
19 - respond_to do |format|  
20 - format.html # show.html.erb  
21 - format.xml { render :xml => @item }  
22 - end  
23 - end  
24 -  
25 - # GET /items/new  
26 - # GET /items/new.xml  
27 - def new  
28 - @item = Item.new  
29 -  
30 - respond_to do |format|  
31 - format.html # new.html.erb  
32 - format.xml { render :xml => @item }  
33 - end  
34 - end  
35 -  
36 - # GET /items/1/edit  
37 - def edit  
38 - @item = Item.find(params[:id])  
39 - end  
40 -  
41 - # POST /items  
42 - # POST /items.xml  
43 - def create  
44 - @item = Item.new(params[:item])  
45 -  
46 - respond_to do |format|  
47 - if @item.save  
48 - flash[:notice] = 'Item was successfully created.'  
49 - format.html { redirect_to(@item) }  
50 - format.xml { render :xml => @item, :status => :created, :location => @item }  
51 - else  
52 - format.html { render :action => "new" }  
53 - format.xml { render :xml => @item.errors, :status => :unprocessable_entity }  
54 - end  
55 - end  
56 - end  
57 -  
58 - # PUT /items/1  
59 - # PUT /items/1.xml  
60 - def update  
61 - @item = Item.find(params[:id])  
62 -  
63 - respond_to do |format|  
64 - if @item.update_attributes(params[:item])  
65 - flash[:notice] = 'Item was successfully updated.'  
66 - format.html { redirect_to(@item) }  
67 - format.xml { head :ok }  
68 - else  
69 - format.html { render :action => "edit" }  
70 - format.xml { render :xml => @item.errors, :status => :unprocessable_entity }  
71 - end  
72 - end  
73 - end  
74 -  
75 - # DELETE /items/1  
76 - # DELETE /items/1.xml  
77 - def destroy  
78 - @item = Item.find(params[:id])  
79 - @item.destroy  
80 -  
81 - respond_to do |format|  
82 - format.html { redirect_to(items_url) }  
83 - format.xml { head :ok }  
84 - end  
85 - end  
86 -end  
app/controllers/prompts_controller.rb
@@ -67,6 +67,7 @@ class PromptsController &lt; InheritedResources::Base @@ -67,6 +67,7 @@ class PromptsController &lt; InheritedResources::Base
67 format.xml { render :xml => @prompt.to_xml, :status => :conflict and return} 67 format.xml { render :xml => @prompt.to_xml, :status => :conflict and return}
68 end 68 end
69 end 69 end
  70 +
70 response = @question.prompts.find(@question_optional_information.delete(:picked_prompt_id)) 71 response = @question.prompts.find(@question_optional_information.delete(:picked_prompt_id))
71 @question_optional_information.each do |key, value| 72 @question_optional_information.each do |key, value|
72 optional_information << Proc.new { |options| options[:builder].tag!(key, value)} 73 optional_information << Proc.new { |options| options[:builder].tag!(key, value)}
@@ -85,7 +86,7 @@ class PromptsController &lt; InheritedResources::Base @@ -85,7 +86,7 @@ class PromptsController &lt; InheritedResources::Base
85 86
86 def show 87 def show
87 @question = current_user.questions.find(params[:question_id]) 88 @question = current_user.questions.find(params[:question_id])
88 - @prompt = @question.prompts.find(params[:id], :include => [{ :left_choice => :item }, { :right_choice => :item }]) 89 + @prompt = @question.prompts.find(params[:id], :include => [:left_choice ,:right_choice ])
89 show! do |format| 90 show! do |format|
90 format.xml { render :xml => @prompt.to_xml(:methods => [:left_choice_text, :right_choice_text])} 91 format.xml { render :xml => @prompt.to_xml(:methods => [:left_choice_text, :right_choice_text])}
91 format.json { render :json => @prompt.to_json(:methods => [:left_choice_text, :right_choice_text])} 92 format.json { render :json => @prompt.to_json(:methods => [:left_choice_text, :right_choice_text])}
app/controllers/questions_controller.rb
@@ -27,12 +27,12 @@ class QuestionsController &lt; InheritedResources::Base @@ -27,12 +27,12 @@ class QuestionsController &lt; InheritedResources::Base
27 end 27 end
28 28
29 def object_info_totals_by_question_id 29 def object_info_totals_by_question_id
30 - total_ideas_by_q_id = Choice.count(:include => ['item', 'question'],  
31 - :conditions => "items.creator_id <> questions.creator_id", 30 + total_ideas_by_q_id = Choice.count(:include => :question,
  31 + :conditions => "choices.creator_id <> questions.creator_id",
32 :group => "choices.question_id") 32 :group => "choices.question_id")
33 33
34 - active_ideas_by_q_id = Choice.count(:include => ['item', 'question'],  
35 - :conditions => "choices.active = 1 AND items.creator_id <> questions.creator_id", 34 + active_ideas_by_q_id = Choice.count(:include => :question,
  35 + :conditions => "choices.active = 1 AND choices.creator_id <> questions.creator_id",
36 :group => "choices.question_id") 36 :group => "choices.question_id")
37 37
38 combined_hash = {} 38 combined_hash = {}
@@ -174,8 +174,7 @@ class QuestionsController &lt; InheritedResources::Base @@ -174,8 +174,7 @@ class QuestionsController &lt; InheritedResources::Base
174 elsif object_type == "uploaded_ideas" 174 elsif object_type == "uploaded_ideas"
175 175
176 uploaded_ideas_by_visitor_id = @question.choices.find(:all, :select => 'creator_id, count(*) as ideas_count', 176 uploaded_ideas_by_visitor_id = @question.choices.find(:all, :select => 'creator_id, count(*) as ideas_count',
177 - :joins => [:item],  
178 - :conditions => "items.creator_id != #{@question.creator_id}", 177 + :conditions => "choices.creator_id != #{@question.creator_id}",
179 :group => 'creator_id') 178 :group => 'creator_id')
180 179
181 count = 0 180 count = 0
@@ -255,8 +254,7 @@ class QuestionsController &lt; InheritedResources::Base @@ -255,8 +254,7 @@ class QuestionsController &lt; InheritedResources::Base
255 elsif object_type == 'skips' 254 elsif object_type == 'skips'
256 hash = Skip.count(:conditions => {:question_id => @question.id}, :group => "date(created_at)") 255 hash = Skip.count(:conditions => {:question_id => @question.id}, :group => "date(created_at)")
257 elsif object_type == 'user_submitted_ideas' 256 elsif object_type == 'user_submitted_ideas'
258 - hash = Choice.count(:include => 'item',  
259 - :conditions => "choices.question_id = #{@question.id} AND items.creator_id <> #{@question.creator_id}", 257 + hash = Choice.count(:conditions => "choices.question_id = #{@question.id} AND choices.creator_id <> #{@question.creator_id}",
260 :group => "date(choices.created_at)") 258 :group => "date(choices.created_at)")
261 # we want graphs to go from date of first vote -> date of last vote, so adding those two boundries here. 259 # we want graphs to go from date of first vote -> date of last vote, so adding those two boundries here.
262 mindate = Vote.minimum('date(created_at)', :conditions => {:question_id => @question.id}) 260 mindate = Vote.minimum('date(created_at)', :conditions => {:question_id => @question.id})
@@ -299,8 +297,8 @@ class QuestionsController &lt; InheritedResources::Base @@ -299,8 +297,8 @@ class QuestionsController &lt; InheritedResources::Base
299 if object_type == 'votes' 297 if object_type == 'votes'
300 hash = Vote.count(:group => "date(created_at)") 298 hash = Vote.count(:group => "date(created_at)")
301 elsif object_type == 'user_submitted_ideas' 299 elsif object_type == 'user_submitted_ideas'
302 - hash = Choice.count(:include => ['item', 'question'],  
303 - :conditions => "items.creator_id <> questions.creator_id", 300 + hash = Choice.count(:include => :question,
  301 + :conditions => "choices.creator_id <> questions.creator_id",
304 :group => "date(choices.created_at)") 302 :group => "date(choices.created_at)")
305 elsif object_type == 'user_sessions' 303 elsif object_type == 'user_sessions'
306 result = Vote.find(:all, :select => 'date(created_at) as date, voter_id, count(*) as vote_count', 304 result = Vote.find(:all, :select => 'date(created_at) as date, voter_id, count(*) as vote_count',
app/controllers/visitors_controller.rb
@@ -7,7 +7,7 @@ class VisitorsController &lt; InheritedResources::Base @@ -7,7 +7,7 @@ class VisitorsController &lt; InheritedResources::Base
7 7
8 visitor_ids = Visitor.find(:all, :conditions => { :identifier => session_ids}) 8 visitor_ids = Visitor.find(:all, :conditions => { :identifier => session_ids})
9 votes_by_visitor_id = Vote.with_voter_ids(visitor_ids).count(:group => :voter_id) 9 votes_by_visitor_id = Vote.with_voter_ids(visitor_ids).count(:group => :voter_id)
10 - ideas_by_visitor_id = Item.with_creator_ids(visitor_ids).count(:group => :creator_id) 10 + ideas_by_visitor_id = Choice.count(:group => :creator_id)
11 11
12 objects_by_session_id = {} 12 objects_by_session_id = {}
13 13
app/helpers/items_helper.rb
@@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
1 -module ItemsHelper  
2 -end  
app/models/choice.rb
1 class Choice < ActiveRecord::Base 1 class Choice < ActiveRecord::Base
2 2
3 belongs_to :question, :counter_cache => true 3 belongs_to :question, :counter_cache => true
4 - belongs_to :item  
5 belongs_to :creator, :class_name => "Visitor", :foreign_key => "creator_id" 4 belongs_to :creator, :class_name => "Visitor", :foreign_key => "creator_id"
6 5
7 validates_presence_of :creator, :on => :create, :message => "can't be blank" 6 validates_presence_of :creator, :on => :create, :message => "can't be blank"
@@ -22,14 +21,6 @@ class Choice &lt; ActiveRecord::Base @@ -22,14 +21,6 @@ class Choice &lt; ActiveRecord::Base
22 end 21 end
23 #attr_accessor :data 22 #attr_accessor :data
24 23
25 - def question_name  
26 - question.name  
27 - end  
28 -  
29 - def item_data  
30 - item.data  
31 - end  
32 -  
33 def lose! 24 def lose!
34 self.loss_count += 1 rescue (self.loss_count = 1) 25 self.loss_count += 1 rescue (self.loss_count = 1)
35 self.score = compute_score 26 self.score = compute_score
@@ -46,6 +37,7 @@ class Choice &lt; ActiveRecord::Base @@ -46,6 +37,7 @@ class Choice &lt; ActiveRecord::Base
46 wins + losses 37 wins + losses
47 end 38 end
48 39
  40 + # TODO delete these and refactor loss_count and votes_count into losses and wins
49 def losses 41 def losses
50 loss_count || 0 42 loss_count || 0
51 end 43 end
@@ -55,11 +47,6 @@ class Choice &lt; ActiveRecord::Base @@ -55,11 +47,6 @@ class Choice &lt; ActiveRecord::Base
55 end 47 end
56 48
57 def before_create 49 def before_create
58 - #puts "just got inside choice#before_create. is set to active? #{self.active?}"  
59 - unless item  
60 - @item = Item.create!(:creator => creator, :data => data)  
61 - self.item = @item  
62 - end  
63 unless self.score 50 unless self.score
64 self.score = 50.0 51 self.score = 50.0
65 end 52 end
@@ -82,7 +69,7 @@ class Choice &lt; ActiveRecord::Base @@ -82,7 +69,7 @@ class Choice &lt; ActiveRecord::Base
82 end 69 end
83 70
84 def user_created 71 def user_created
85 - self.item.creator_id != self.question.creator_id 72 + self.creator_id != self.question.creator_id
86 end 73 end
87 74
88 def compute_bt_score(btprobs = nil) 75 def compute_bt_score(btprobs = nil)
@@ -110,11 +97,6 @@ class Choice &lt; ActiveRecord::Base @@ -110,11 +97,6 @@ class Choice &lt; ActiveRecord::Base
110 self.save! 97 self.save!
111 end 98 end
112 99
113 - def suspend!  
114 - (self.active = false)  
115 - self.save!  
116 - end  
117 -  
118 def deactivate! 100 def deactivate!
119 (self.active = false) 101 (self.active = false)
120 self.save! 102 self.save!
app/models/item.rb
@@ -1,24 +0,0 @@ @@ -1,24 +0,0 @@
1 -class Item < ActiveRecord::Base  
2 - belongs_to :question, :counter_cache => true  
3 - belongs_to :site, :class_name => "User", :foreign_key => "site_id"  
4 - belongs_to :creator, :class_name => "Visitor", :foreign_key => "creator_id"  
5 -  
6 - named_scope :active, :conditions => { :active => true }  
7 - named_scope :with_creator_ids, lambda { |*args| {:conditions => {:creator_id=> args.first }} }  
8 -  
9 - # has_many :items_questions, :dependent => :destroy  
10 - # has_many :questions, :through => :items_questions  
11 - # has_and_belongs_to_many :prompts  
12 - #  
13 - # has_and_belongs_to_many :votes  
14 - # has_and_belongs_to_many :prompt_requests  
15 -  
16 - validates_presence_of :creator_id  
17 - validates_presence_of :data, :on => :create, :message => "can't be blank"  
18 -  
19 - def self.mass_insert!(creator_id, data_array)  
20 - #alpha  
21 - inserts = data_array.collect{|i| "(#{connection.quote i}, #{connection.quote creator_id})"}.join(", ")  
22 - connection.insert("INSERT INTO items(data, creator_id) VALUES (#{inserts})")  
23 - end  
24 -end  
app/models/prompt.rb
@@ -10,6 +10,9 @@ class Prompt &lt; ActiveRecord::Base @@ -10,6 +10,9 @@ class Prompt &lt; ActiveRecord::Base
10 belongs_to :left_choice, :class_name => "Choice", :foreign_key => "left_choice_id", :counter_cache => true 10 belongs_to :left_choice, :class_name => "Choice", :foreign_key => "left_choice_id", :counter_cache => true
11 belongs_to :right_choice, :class_name => "Choice", :foreign_key => "right_choice_id", :counter_cache => true 11 belongs_to :right_choice, :class_name => "Choice", :foreign_key => "right_choice_id", :counter_cache => true
12 12
  13 + validates_presence_of :left_choice, :on => :create, :message => "can't be blank"
  14 + validates_presence_of :right_choice, :on => :create, :message => "can't be blank"
  15 +
13 named_scope :with_left_choice, lambda { |*args| {:conditions => ["left_choice_id = ?", (args.first.id)]} } 16 named_scope :with_left_choice, lambda { |*args| {:conditions => ["left_choice_id = ?", (args.first.id)]} }
14 named_scope :with_right_choice, lambda { |*args| {:conditions => ["right_choice_id = ?", (args.first.id)]} } 17 named_scope :with_right_choice, lambda { |*args| {:conditions => ["right_choice_id = ?", (args.first.id)]} }
15 named_scope :with_choice, lambda { |*args| {:conditions => ["(right_choice_id = ?) OR (left_choice_id = ?)", (args.first.id)]} } 18 named_scope :with_choice, lambda { |*args| {:conditions => ["(right_choice_id = ?) OR (left_choice_id = ?)", (args.first.id)]} }
@@ -25,8 +28,6 @@ class Prompt &lt; ActiveRecord::Base @@ -25,8 +28,6 @@ class Prompt &lt; ActiveRecord::Base
25 select {|z| z.voted_on_by_user?(u)} 28 select {|z| z.voted_on_by_user?(u)}
26 end 29 end
27 30
28 - validates_presence_of :left_choice, :on => :create, :message => "can't be blank"  
29 - validates_presence_of :right_choice, :on => :create, :message => "can't be blank"  
30 31
31 def choices 32 def choices
32 [left_choice, right_choice] 33 [left_choice, right_choice]
@@ -37,7 +38,7 @@ class Prompt &lt; ActiveRecord::Base @@ -37,7 +38,7 @@ class Prompt &lt; ActiveRecord::Base
37 end 38 end
38 39
39 def left_choice_text(prompt = nil) 40 def left_choice_text(prompt = nil)
40 - left_choice.item.data 41 + left_choice.data
41 end 42 end
42 43
43 def active? 44 def active?
@@ -46,7 +47,7 @@ class Prompt &lt; ActiveRecord::Base @@ -46,7 +47,7 @@ class Prompt &lt; ActiveRecord::Base
46 47
47 48
48 def right_choice_text(prompt = nil) 49 def right_choice_text(prompt = nil)
49 - right_choice.item.data 50 + right_choice.data
50 end 51 end
51 52
52 end 53 end
app/models/question.rb
@@ -26,8 +26,7 @@ class Question &lt; ActiveRecord::Base @@ -26,8 +26,7 @@ class Question &lt; ActiveRecord::Base
26 def create_choices_from_ideas 26 def create_choices_from_ideas
27 if ideas && ideas.any? 27 if ideas && ideas.any?
28 ideas.each do |idea| 28 ideas.each do |idea|
29 - item = Item.create!(:data => idea.squish.strip, :creator => self.creator)  
30 - choices.create!(:item => item, :creator => self.creator, :active => true, :data => idea.squish.strip) 29 + choices.create!(:creator => self.creator, :active => true, :data => idea.squish.strip)
31 end 30 end
32 end 31 end
33 end 32 end
@@ -70,7 +69,7 @@ class Question &lt; ActiveRecord::Base @@ -70,7 +69,7 @@ class Question &lt; ActiveRecord::Base
70 raise NotImplementedError.new("Sorry, we currently only support pairwise prompts. Rank of the prompt must be 2.") unless rank == 2 69 raise NotImplementedError.new("Sorry, we currently only support pairwise prompts. Rank of the prompt must be 2.") unless rank == 2
71 begin 70 begin
72 choice_id_array = distinct_array_of_choice_ids(rank) 71 choice_id_array = distinct_array_of_choice_ids(rank)
73 - @p = prompts.find_or_create_by_left_choice_id_and_right_choice_id(choice_id_array[0], choice_id_array[1], :include => [{ :left_choice => :item }, { :right_choice => :item }]) 72 + @p = prompts.find_or_create_by_left_choice_id_and_right_choice_id(choice_id_array[0], choice_id_array[1], :include => [:left_choice ,:right_choice ])
74 logger.info "#{@p.inspect} is active? #{@p.active?}" 73 logger.info "#{@p.inspect} is active? #{@p.active?}"
75 end until @p.active? 74 end until @p.active?
76 return @p 75 return @p
@@ -173,7 +172,7 @@ class Question &lt; ActiveRecord::Base @@ -173,7 +172,7 @@ class Question &lt; ActiveRecord::Base
173 if params[:with_visitor_stats] 172 if params[:with_visitor_stats]
174 visitor = current_user.visitors.find_or_create_by_identifier(visitor_identifier) 173 visitor = current_user.visitors.find_or_create_by_identifier(visitor_identifier)
175 result.merge!(:visitor_votes => visitor.votes.count(:conditions => {:question_id => self.id})) 174 result.merge!(:visitor_votes => visitor.votes.count(:conditions => {:question_id => self.id}))
176 - result.merge!(:visitor_ideas => visitor.items.count) 175 + result.merge!(:visitor_ideas => visitor.choices.count)
177 end 176 end
178 177
179 return result 178 return result
@@ -303,14 +302,6 @@ class Question &lt; ActiveRecord::Base @@ -303,14 +302,6 @@ class Question &lt; ActiveRecord::Base
303 picked_prompt.id 302 picked_prompt.id
304 end 303 end
305 304
306 - def left_choice_text(prompt = nil)  
307 - picked_prompt.left_choice.item.data  
308 - end  
309 -  
310 - def right_choice_text(prompt = nil)  
311 - picked_prompt.right_choice.item.data  
312 - end  
313 -  
314 def self.voted_on_by(u) 305 def self.voted_on_by(u)
315 select {|z| z.voted_on_by_user?(u)} 306 select {|z| z.voted_on_by_user?(u)}
316 end 307 end
@@ -516,7 +507,7 @@ class Question &lt; ActiveRecord::Base @@ -516,7 +507,7 @@ class Question &lt; ActiveRecord::Base
516 num_skips = self.skips.count(:conditions => {:prompt_id => left_prompts_ids + right_prompts_ids}) 507 num_skips = self.skips.count(:conditions => {:prompt_id => left_prompts_ids + right_prompts_ids})
517 508
518 csv << [c.question_id, c.id, "'#{c.data.strip}'", c.wins, c.losses, num_skips, c.score, 509 csv << [c.question_id, c.id, "'#{c.data.strip}'", c.wins, c.losses, num_skips, c.score,
519 - user_submitted , c.item.creator_id, c.created_at, c.updated_at, c.active, 510 + user_submitted , c.creator_id, c.created_at, c.updated_at, c.active,
520 left_appearances, right_appearances] 511 left_appearances, right_appearances]
521 end 512 end
522 when 'non_votes' 513 when 'non_votes'
app/models/user.rb
@@ -3,7 +3,6 @@ class User &lt; ActiveRecord::Base @@ -3,7 +3,6 @@ class User &lt; ActiveRecord::Base
3 has_many :visitors, :class_name => "Visitor", :foreign_key => "site_id" 3 has_many :visitors, :class_name => "Visitor", :foreign_key => "site_id"
4 has_many :questions, :class_name => "Question", :foreign_key => "site_id" 4 has_many :questions, :class_name => "Question", :foreign_key => "site_id"
5 has_many :clicks, :class_name => "Click", :foreign_key => "site_id" 5 has_many :clicks, :class_name => "Click", :foreign_key => "site_id"
6 - has_many :items, :class_name => "Item", :foreign_key => "site_id"  
7 6
8 def default_visitor 7 def default_visitor
9 visitors.find(:first, :conditions => {:identifier => 'owner'}) 8 visitors.find(:first, :conditions => {:identifier => 'owner'})
@@ -62,16 +61,6 @@ class User &lt; ActiveRecord::Base @@ -62,16 +61,6 @@ class User &lt; ActiveRecord::Base
62 question.activate! 61 question.activate!
63 end 62 end
64 63
65 - def activate_choice(choice_id, options)  
66 - choice = Choice.find(choice_id)  
67 - choice.activate!  
68 - end  
69 -  
70 - def deactivate_choice(choice_id, options)  
71 - choice = Choice.find(choice_id)  
72 - choice.deactivate!  
73 - end  
74 -  
75 def deactivate_question(question_id, options) 64 def deactivate_question(question_id, options)
76 question = questions.find(question_id) 65 question = questions.find(question_id)
77 question.deactivate! 66 question.deactivate!
app/models/visitor.rb
@@ -3,7 +3,7 @@ class Visitor &lt; ActiveRecord::Base @@ -3,7 +3,7 @@ class Visitor &lt; ActiveRecord::Base
3 has_many :questions, :class_name => "Question", :foreign_key => "creator_id" 3 has_many :questions, :class_name => "Question", :foreign_key => "creator_id"
4 has_many :votes, :class_name => "Vote", :foreign_key => "voter_id" 4 has_many :votes, :class_name => "Vote", :foreign_key => "voter_id"
5 has_many :skips, :class_name => "Skip", :foreign_key => "skipper_id" 5 has_many :skips, :class_name => "Skip", :foreign_key => "skipper_id"
6 - has_many :items, :class_name => "Item", :foreign_key => "creator_id" 6 + has_many :choices, :class_name => "Choice", :foreign_key => "creator_id"
7 has_many :clicks 7 has_many :clicks
8 has_many :appearances, :foreign_key => "voter_id" 8 has_many :appearances, :foreign_key => "voter_id"
9 9
app/views/items/edit.html.erb
@@ -1,12 +0,0 @@ @@ -1,12 +0,0 @@
1 -<h1>Editing item</h1>  
2 -  
3 -<% form_for(@item) do |f| %>  
4 - <%= f.error_messages %>  
5 -  
6 - <p>  
7 - <%= f.submit 'Update' %>  
8 - </p>  
9 -<% end %>  
10 -  
11 -<%= link_to 'Show', @item %> |  
12 -<%= link_to 'Back', items_path %>  
13 \ No newline at end of file 0 \ No newline at end of file
app/views/items/index.html.erb
@@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
1 -<h1>Listing items</h1>  
2 -  
3 -<table>  
4 - <tr>  
5 - </tr>  
6 -  
7 -<% @items.each do |item| %>  
8 - <tr>  
9 - <td><%= link_to 'Show', item %></td>  
10 - <td><%= link_to 'Edit', edit_item_path(item) %></td>  
11 - <td><%= link_to 'Destroy', item, :confirm => 'Are you sure?', :method => :delete %></td>  
12 - </tr>  
13 -<% end %>  
14 -</table>  
15 -  
16 -<br />  
17 -  
18 -<%= link_to 'New item', new_item_path %>  
19 \ No newline at end of file 0 \ No newline at end of file
app/views/items/new.html.erb
@@ -1,11 +0,0 @@ @@ -1,11 +0,0 @@
1 -<h1>New item</h1>  
2 -  
3 -<% form_for(@item) do |f| %>  
4 - <%= f.error_messages %>  
5 -  
6 - <p>  
7 - <%= f.submit 'Create' %>  
8 - </p>  
9 -<% end %>  
10 -  
11 -<%= link_to 'Back', items_path %>  
12 \ No newline at end of file 0 \ No newline at end of file
app/views/items/show.html.erb
@@ -1,3 +0,0 @@ @@ -1,3 +0,0 @@
1 -  
2 -<%= link_to 'Edit', edit_item_path(@item) %> |  
3 -<%= link_to 'Back', items_path %>  
4 \ No newline at end of file 0 \ No newline at end of file
app/views/layouts/items.html.erb
@@ -1,17 +0,0 @@ @@ -1,17 +0,0 @@
1 -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
2 - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
3 -  
4 -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">  
5 -<head>  
6 - <meta http-equiv="content-type" content="text/html;charset=UTF-8" />  
7 - <title>Items: <%= controller.action_name %></title>  
8 - <%= stylesheet_link_tag 'scaffold' %>  
9 -</head>  
10 -<body>  
11 -  
12 -<p style="color: green"><%= flash[:notice] %></p>  
13 -  
14 -<%= yield %>  
15 -  
16 -</body>  
17 -</html>  
db/migrate/20100621162849_add_creator_to_choices.rb 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +class AddCreatorToChoices < ActiveRecord::Migration
  2 + def self.up
  3 + add_column :choices, :creator_id, :integer
  4 + Choice.find(:all, :include => [:item]).each do |c|
  5 + c.creator_id = c.item.creator_id
  6 + c.save
  7 + end
  8 + end
  9 +
  10 + def self.down
  11 + remove_column :choices, :creator_id
  12 + end
  13 +end
lib/tasks/test_api.rake
@@ -496,16 +496,18 @@ namespace :test_api do @@ -496,16 +496,18 @@ namespace :test_api do
496 496
497 question.expire_prompt_cache_tracking_keys(Date.yesterday) 497 question.expire_prompt_cache_tracking_keys(Date.yesterday)
498 498
499 - yesterday_votes = question.appearances.count(:conditions => ['date(created_at) = ?', Date.yesterday]) 499 + yesterday_appearances = question.appearances.count(:conditions => ['date(created_at) = ?', Date.yesterday])
500 500
501 - if misses + hits != yesterday_votes  
502 - error_message += "Error! Question #{question.id} isn't tracking prompt cache hits and misses accurately! Expected #{yesterday_votes}, Actual: #{misses+hits}\n"  
503 - end  
504 -  
505 - miss_rate = misses.to_f / yesterday_votes.to_f  
506 - if miss_rate > 0.1  
507 - error_message += "Error! Question #{question.id} has less than 90% of appearances taken from a pre-generated cache! Expected <#{0.1}, Actual: #{miss_rate}\n" 501 + if misses + hits != yesterday_appearances
  502 + error_message += "Error! Question #{question.id} isn't tracking prompt cache hits and misses accurately! Expected #{yesterday_appearances}, Actual: #{misses+hits}\n"
508 end 503 end
  504 +
  505 + if yesterday_appearances > 5 # this test isn't worthwhile for small numbers of appearances
  506 + miss_rate = misses.to_f / yesterday_appearances.to_f
  507 + if miss_rate > 0.1
  508 + error_message += "Error! Question #{question.id} has less than 90% of appearances taken from a pre-generated cache! Expected <#{0.1}, Actual: #{miss_rate}, total appearances yesterday: #{yesterday_appearances}\n"
  509 + end
  510 + end
509 return error_message.blank? ? [success_message, false] : [error_message, true] 511 return error_message.blank? ? [success_message, false] : [error_message, true]
510 end 512 end
511 513
spec/models/choice_spec.rb
@@ -3,14 +3,18 @@ require File.expand_path(File.dirname(__FILE__) + &#39;/../spec_helper&#39;) @@ -3,14 +3,18 @@ require File.expand_path(File.dirname(__FILE__) + &#39;/../spec_helper&#39;)
3 describe Choice do 3 describe Choice do
4 4
5 it {should belong_to :question} 5 it {should belong_to :question}
6 - it {should belong_to :item} 6 + it {should belong_to :creator}
7 it {should have_many :flags} 7 it {should have_many :flags}
  8 + it {should have_many :votes}
  9 + it {should have_many :prompts_on_the_left}
  10 + it {should have_many :prompts_on_the_right}
8 it {should validate_presence_of :question} 11 it {should validate_presence_of :question}
  12 + it {should validate_presence_of :creator}
9 13
10 before(:each) do 14 before(:each) do
11 @aoi_clone = Factory.create(:email_confirmed_user) 15 @aoi_clone = Factory.create(:email_confirmed_user)
12 @visitor= Factory.create(:visitor, :site => @aoi_clone) 16 @visitor= Factory.create(:visitor, :site => @aoi_clone)
13 - @question = Question.create(:name => 'which do you like better?', 17 + @question = Factory.create(:aoi_question, :name => "Which do you like better?",
14 :site => @aoi_clone, 18 :site => @aoi_clone,
15 :creator => @visitor) 19 :creator => @visitor)
16 20
@@ -25,13 +29,6 @@ describe Choice do @@ -25,13 +29,6 @@ describe Choice do
25 Choice.create!(@valid_attributes) 29 Choice.create!(@valid_attributes)
26 end 30 end
27 31
28 - #it "should generate prompts after two choices are created" do  
29 - # proc {  
30 -# choice1 = Choice.create!(@valid_attributes.merge(:data => '1234'))  
31 -# choice2 = Choice.create!(@valid_attributes.merge(:data => '1234'))  
32 -# }.should change(@question.prompts, :count).by(2)  
33 -# end  
34 -  
35 it "should deactivate a choice" do 32 it "should deactivate a choice" do
36 choice1 = Choice.create!(@valid_attributes.merge(:data => '1234')) 33 choice1 = Choice.create!(@valid_attributes.merge(:data => '1234'))
37 choice1.deactivate! 34 choice1.deactivate!
@@ -39,12 +36,14 @@ describe Choice do @@ -39,12 +36,14 @@ describe Choice do
39 end 36 end
40 37
41 it "should update a question's counter cache on creation" do 38 it "should update a question's counter cache on creation" do
42 - @question.choices_count.should == 0  
43 - @question.choices.size.should == 0  
44 - Choice.create!(@valid_attributes.merge(:data => '1234'))  
45 - @question.reload  
46 - @question.choices_count.should == 1  
47 - @question.choices.size.should == 1 39 + # not an allour ideas question
  40 + question = Factory.create(:question, :site => @aoi_clone, :creator => @visitor)
  41 + question.choices_count.should == 0
  42 + question.choices.size.should == 0
  43 + Choice.create!(@valid_attributes.merge(:question => question))
  44 + question.reload
  45 + question.choices_count.should == 1
  46 + question.choices.size.should == 1
48 47
49 end 48 end
50 49
@@ -67,4 +66,61 @@ describe Choice do @@ -67,4 +66,61 @@ describe Choice do
67 @question.reload 66 @question.reload
68 @question.inactive_choices_count.should == prev_inactive + 1 67 @question.inactive_choices_count.should == prev_inactive + 1
69 end 68 end
  69 + it "should have a default score of 50" do
  70 + choice1 = Choice.create!(@valid_attributes)
  71 + choice1.score.should == 50
  72 + end
  73 + it "correctly compute a score based on wins and losses" do
  74 + choice1 = Choice.create!(@valid_attributes)
  75 + choice1.votes_count = 30
  76 + choice1.loss_count = 70
  77 + choice1.compute_score.should be_close(30,1)
  78 + end
  79 + it "compute score and save" do
  80 + choice1 = Choice.create!(@valid_attributes)
  81 + choice1.score.should == 50
  82 + choice1.votes_count= 30
  83 + choice1.loss_count = 70
  84 + choice1.compute_score!
  85 + choice1.score.should be_close(30, 1)
  86 + end
  87 +
  88 + it "determines whether a choice is admin created" do
  89 + admin_choice = @question.choices.first
  90 + admin_choice.user_created.should be_false
  91 + end
  92 + it "determines whether a choice is user created" do
  93 + new_visitor = Factory.create(:visitor, :site => @aoi_clone)
  94 + user_choice = Factory.create(:choice, :question => @question, :creator => new_visitor)
  95 + user_choice.user_created.should be_true
  96 + end
  97 +
  98 + describe "voting updates things" do
  99 + before do
  100 + @prompt = @question.choose_prompt
  101 + @winning_choice = @prompt.left_choice
  102 + @losing_choice = @prompt.right_choice
  103 + @winning_choice.win!
  104 + @losing_choice.lose!
  105 + end
  106 +
  107 + it "should update score on a win" do
  108 + @winning_choice.score.should be_close(67, 1)
  109 + end
  110 + it "should update score on a loss" do
  111 + @losing_choice.score.should be_close(33,1)
  112 + end
  113 + it "should update win count on a win" do
  114 + @winning_choice.votes_count.should == 1
  115 + @winning_choice.wins.should == 1
  116 + @winning_choice.loss_count.should == 0
  117 + @winning_choice.losses.should == 0
  118 + end
  119 + it "should update loss count on a loss" do
  120 + @losing_choice.votes_count.should == 0
  121 + @losing_choice.wins.should == 0
  122 + @losing_choice.loss_count.should == 1
  123 + @losing_choice.losses.should == 1
  124 + end
  125 + end
70 end 126 end
spec/models/item_spec.rb
@@ -1,21 +0,0 @@ @@ -1,21 +0,0 @@
1 -require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')  
2 -  
3 -describe Item do  
4 - it {should belong_to :creator}  
5 - it {should belong_to :site}  
6 - it {should validate_presence_of :data}  
7 -  
8 - before(:each) do  
9 - @aoi_clone = Factory.create(:user, :email => "pius@alum.mit.edu", :password => "password", :password_confirmation => "password", :id => 8)  
10 - @johndoe = Factory.create(:visitor, :identifier => 'johndoe', :site => @aoi_clone)  
11 - @valid_attributes = {  
12 - :site => @aoi_clone,  
13 - :creator => @johndoe,  
14 - :data => 'a widget'  
15 - }  
16 - end  
17 -  
18 - it "should create a new instance given valid attributes" do  
19 - Item.create!(@valid_attributes)  
20 - end  
21 -end  
spec/models/prompt_spec.rb
@@ -4,5 +4,16 @@ describe Prompt do @@ -4,5 +4,16 @@ describe Prompt do
4 it {should belong_to :question} 4 it {should belong_to :question}
5 it {should belong_to :left_choice} 5 it {should belong_to :left_choice}
6 it {should belong_to :right_choice} 6 it {should belong_to :right_choice}
  7 + before(:each) do
  8 + @question = Factory.create(:aoi_question)
  9 + @prompt = @question.prompts.first
  10 + end
  11 +
  12 + it "should display left choice text" do
  13 + @prompt.left_choice_text.should == @prompt.left_choice.data
  14 + end
7 15
  16 + it "should display right choice text" do
  17 + @prompt.right_choice_text.should == @prompt.right_choice.data
  18 + end
8 end 19 end
spec/models/question_spec.rb
@@ -112,6 +112,12 @@ describe Question do @@ -112,6 +112,12 @@ describe Question do
112 @question_optional_information[:picked_prompt_id].should == saved_prompt_id 112 @question_optional_information[:picked_prompt_id].should == saved_prompt_id
113 end 113 end
114 114
  115 + it "should auto create ideas when 'ideas' attribute is set" do
  116 + @question = Factory.build(:question)
  117 + @question.ideas = %w(one two three)
  118 + @question.save
  119 + @question.choices.count.should == 3
  120 + end
115 context "catchup algorithm" do 121 context "catchup algorithm" do
116 before(:all) do 122 before(:all) do
117 @catchup_q = Factory.create(:aoi_question) 123 @catchup_q = Factory.create(:aoi_question)
@@ -283,7 +289,6 @@ describe Question do @@ -283,7 +289,6 @@ describe Question do
283 rows.first.should include("Record ID") 289 rows.first.should include("Record ID")
284 rows.first.should include("Record Type") 290 rows.first.should include("Record Type")
285 rows.first.should_not include("Idea ID") 291 rows.first.should_not include("Idea ID")
286 - puts filename  
287 File.delete(filename).should_not be_nil 292 File.delete(filename).should_not be_nil
288 293
289 294
@@ -300,7 +305,6 @@ describe Question do @@ -300,7 +305,6 @@ describe Question do
300 rows = FasterCSV.read(filename) 305 rows = FasterCSV.read(filename)
301 rows.first.should include("Idea ID") 306 rows.first.should include("Idea ID")
302 rows.first.should_not include("Skip ID") 307 rows.first.should_not include("Skip ID")
303 - puts filename  
304 File.delete(filename).should_not be_nil 308 File.delete(filename).should_not be_nil
305 309
306 end 310 end
spec/models/visitor_spec.rb
@@ -8,6 +8,7 @@ describe Visitor do @@ -8,6 +8,7 @@ describe Visitor do
8 it {should have_many :skips} 8 it {should have_many :skips}
9 it {should have_many :clicks} 9 it {should have_many :clicks}
10 it {should have_many :appearances} 10 it {should have_many :appearances}
  11 + it {should have_many :choices}
11 12
12 before(:each) do 13 before(:each) do
13 @question = Factory.create(:aoi_question) 14 @question = Factory.create(:aoi_question)