Commit 5fc443583add3894661117c188eadf0d71db2ced
Exists in
master
and in
1 other branch
Merge branch 'master' of http://github.com/allourideas/pairwise2
Conflicts: app/controllers/prompts_controller.rb
Showing
24 changed files
with
140 additions
and
285 deletions
Show diff stats
app/controllers/choices_controller.rb
| ... | ... | @@ -12,8 +12,8 @@ class ChoicesController < InheritedResources::Base |
| 12 | 12 | |
| 13 | 13 | find_options = {:conditions => {:question_id => @question.id}, |
| 14 | 14 | :limit => params[:limit].to_i, |
| 15 | - :order => 'score DESC', | |
| 16 | - :include => :item} | |
| 15 | + :order => 'score DESC' | |
| 16 | + } | |
| 17 | 17 | |
| 18 | 18 | find_options[:conditions].merge!(:active => true) unless params[:include_inactive] |
| 19 | 19 | find_options.merge!(:offset => params[:offset]) if params[:offset] |
| ... | ... | @@ -23,9 +23,9 @@ class ChoicesController < InheritedResources::Base |
| 23 | 23 | else |
| 24 | 24 | @question = Question.find(params[:question_id], :include => :choices) #eagerloads ALL choices |
| 25 | 25 | unless params[:include_inactive] |
| 26 | - @choices = @question.choices(true).active.find(:all, :include => :item) | |
| 26 | + @choices = @question.choices(true).active.find(:all) | |
| 27 | 27 | else |
| 28 | - @choices = @question.choices.find(:all, :include =>:item) | |
| 28 | + @choices = @question.choices.find(:all) | |
| 29 | 29 | end |
| 30 | 30 | end |
| 31 | 31 | index! do |format| |
| ... | ... | @@ -38,7 +38,7 @@ class ChoicesController < InheritedResources::Base |
| 38 | 38 | show! do |format| |
| 39 | 39 | format.xml { |
| 40 | 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 | 42 | format.json { render :json => @choice.to_json(:methods => [:data])} |
| 43 | 43 | end |
| 44 | 44 | end | ... | ... |
app/controllers/items_controller.rb
| ... | ... | @@ -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 < InheritedResources::Base |
| 67 | 67 | format.xml { render :xml => @prompt.to_xml, :status => :conflict and return} |
| 68 | 68 | end |
| 69 | 69 | end |
| 70 | + | |
| 70 | 71 | response = @question.prompts.find(@question_optional_information.delete(:picked_prompt_id)) |
| 71 | 72 | @question_optional_information.each do |key, value| |
| 72 | 73 | optional_information << Proc.new { |options| options[:builder].tag!(key, value)} |
| ... | ... | @@ -85,7 +86,7 @@ class PromptsController < InheritedResources::Base |
| 85 | 86 | |
| 86 | 87 | def show |
| 87 | 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 | 90 | show! do |format| |
| 90 | 91 | format.xml { render :xml => @prompt.to_xml(:methods => [:left_choice_text, :right_choice_text])} |
| 91 | 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 < InheritedResources::Base |
| 27 | 27 | end |
| 28 | 28 | |
| 29 | 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 | 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 | 36 | :group => "choices.question_id") |
| 37 | 37 | |
| 38 | 38 | combined_hash = {} |
| ... | ... | @@ -174,8 +174,7 @@ class QuestionsController < InheritedResources::Base |
| 174 | 174 | elsif object_type == "uploaded_ideas" |
| 175 | 175 | |
| 176 | 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 | 178 | :group => 'creator_id') |
| 180 | 179 | |
| 181 | 180 | count = 0 |
| ... | ... | @@ -255,8 +254,7 @@ class QuestionsController < InheritedResources::Base |
| 255 | 254 | elsif object_type == 'skips' |
| 256 | 255 | hash = Skip.count(:conditions => {:question_id => @question.id}, :group => "date(created_at)") |
| 257 | 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 | 258 | :group => "date(choices.created_at)") |
| 261 | 259 | # we want graphs to go from date of first vote -> date of last vote, so adding those two boundries here. |
| 262 | 260 | mindate = Vote.minimum('date(created_at)', :conditions => {:question_id => @question.id}) |
| ... | ... | @@ -299,8 +297,8 @@ class QuestionsController < InheritedResources::Base |
| 299 | 297 | if object_type == 'votes' |
| 300 | 298 | hash = Vote.count(:group => "date(created_at)") |
| 301 | 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 | 302 | :group => "date(choices.created_at)") |
| 305 | 303 | elsif object_type == 'user_sessions' |
| 306 | 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 < InheritedResources::Base |
| 7 | 7 | |
| 8 | 8 | visitor_ids = Visitor.find(:all, :conditions => { :identifier => session_ids}) |
| 9 | 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 | 12 | objects_by_session_id = {} |
| 13 | 13 | ... | ... |
app/helpers/items_helper.rb
app/models/choice.rb
| 1 | 1 | class Choice < ActiveRecord::Base |
| 2 | 2 | |
| 3 | 3 | belongs_to :question, :counter_cache => true |
| 4 | - belongs_to :item | |
| 5 | 4 | belongs_to :creator, :class_name => "Visitor", :foreign_key => "creator_id" |
| 6 | 5 | |
| 7 | 6 | validates_presence_of :creator, :on => :create, :message => "can't be blank" |
| ... | ... | @@ -22,14 +21,6 @@ class Choice < ActiveRecord::Base |
| 22 | 21 | end |
| 23 | 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 | 24 | def lose! |
| 34 | 25 | self.loss_count += 1 rescue (self.loss_count = 1) |
| 35 | 26 | self.score = compute_score |
| ... | ... | @@ -46,6 +37,7 @@ class Choice < ActiveRecord::Base |
| 46 | 37 | wins + losses |
| 47 | 38 | end |
| 48 | 39 | |
| 40 | + # TODO delete these and refactor loss_count and votes_count into losses and wins | |
| 49 | 41 | def losses |
| 50 | 42 | loss_count || 0 |
| 51 | 43 | end |
| ... | ... | @@ -55,11 +47,6 @@ class Choice < ActiveRecord::Base |
| 55 | 47 | end |
| 56 | 48 | |
| 57 | 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 | 50 | unless self.score |
| 64 | 51 | self.score = 50.0 |
| 65 | 52 | end |
| ... | ... | @@ -82,7 +69,7 @@ class Choice < ActiveRecord::Base |
| 82 | 69 | end |
| 83 | 70 | |
| 84 | 71 | def user_created |
| 85 | - self.item.creator_id != self.question.creator_id | |
| 72 | + self.creator_id != self.question.creator_id | |
| 86 | 73 | end |
| 87 | 74 | |
| 88 | 75 | def compute_bt_score(btprobs = nil) |
| ... | ... | @@ -110,11 +97,6 @@ class Choice < ActiveRecord::Base |
| 110 | 97 | self.save! |
| 111 | 98 | end |
| 112 | 99 | |
| 113 | - def suspend! | |
| 114 | - (self.active = false) | |
| 115 | - self.save! | |
| 116 | - end | |
| 117 | - | |
| 118 | 100 | def deactivate! |
| 119 | 101 | (self.active = false) |
| 120 | 102 | self.save! | ... | ... |
app/models/item.rb
| ... | ... | @@ -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 < ActiveRecord::Base |
| 10 | 10 | belongs_to :left_choice, :class_name => "Choice", :foreign_key => "left_choice_id", :counter_cache => true |
| 11 | 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 | 16 | named_scope :with_left_choice, lambda { |*args| {:conditions => ["left_choice_id = ?", (args.first.id)]} } |
| 14 | 17 | named_scope :with_right_choice, lambda { |*args| {:conditions => ["right_choice_id = ?", (args.first.id)]} } |
| 15 | 18 | named_scope :with_choice, lambda { |*args| {:conditions => ["(right_choice_id = ?) OR (left_choice_id = ?)", (args.first.id)]} } |
| ... | ... | @@ -25,8 +28,6 @@ class Prompt < ActiveRecord::Base |
| 25 | 28 | select {|z| z.voted_on_by_user?(u)} |
| 26 | 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 | 32 | def choices |
| 32 | 33 | [left_choice, right_choice] |
| ... | ... | @@ -37,7 +38,7 @@ class Prompt < ActiveRecord::Base |
| 37 | 38 | end |
| 38 | 39 | |
| 39 | 40 | def left_choice_text(prompt = nil) |
| 40 | - left_choice.item.data | |
| 41 | + left_choice.data | |
| 41 | 42 | end |
| 42 | 43 | |
| 43 | 44 | def active? |
| ... | ... | @@ -46,7 +47,7 @@ class Prompt < ActiveRecord::Base |
| 46 | 47 | |
| 47 | 48 | |
| 48 | 49 | def right_choice_text(prompt = nil) |
| 49 | - right_choice.item.data | |
| 50 | + right_choice.data | |
| 50 | 51 | end |
| 51 | 52 | |
| 52 | 53 | end | ... | ... |
app/models/question.rb
| ... | ... | @@ -26,8 +26,7 @@ class Question < ActiveRecord::Base |
| 26 | 26 | def create_choices_from_ideas |
| 27 | 27 | if ideas && ideas.any? |
| 28 | 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 | 30 | end |
| 32 | 31 | end |
| 33 | 32 | end |
| ... | ... | @@ -70,7 +69,7 @@ class Question < ActiveRecord::Base |
| 70 | 69 | raise NotImplementedError.new("Sorry, we currently only support pairwise prompts. Rank of the prompt must be 2.") unless rank == 2 |
| 71 | 70 | begin |
| 72 | 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 | 73 | logger.info "#{@p.inspect} is active? #{@p.active?}" |
| 75 | 74 | end until @p.active? |
| 76 | 75 | return @p |
| ... | ... | @@ -173,7 +172,7 @@ class Question < ActiveRecord::Base |
| 173 | 172 | if params[:with_visitor_stats] |
| 174 | 173 | visitor = current_user.visitors.find_or_create_by_identifier(visitor_identifier) |
| 175 | 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 | 176 | end |
| 178 | 177 | |
| 179 | 178 | return result |
| ... | ... | @@ -303,14 +302,6 @@ class Question < ActiveRecord::Base |
| 303 | 302 | picked_prompt.id |
| 304 | 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 | 305 | def self.voted_on_by(u) |
| 315 | 306 | select {|z| z.voted_on_by_user?(u)} |
| 316 | 307 | end |
| ... | ... | @@ -516,7 +507,7 @@ class Question < ActiveRecord::Base |
| 516 | 507 | num_skips = self.skips.count(:conditions => {:prompt_id => left_prompts_ids + right_prompts_ids}) |
| 517 | 508 | |
| 518 | 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 | 511 | left_appearances, right_appearances] |
| 521 | 512 | end |
| 522 | 513 | when 'non_votes' | ... | ... |
app/models/user.rb
| ... | ... | @@ -3,7 +3,6 @@ class User < ActiveRecord::Base |
| 3 | 3 | has_many :visitors, :class_name => "Visitor", :foreign_key => "site_id" |
| 4 | 4 | has_many :questions, :class_name => "Question", :foreign_key => "site_id" |
| 5 | 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 | 7 | def default_visitor |
| 9 | 8 | visitors.find(:first, :conditions => {:identifier => 'owner'}) |
| ... | ... | @@ -62,16 +61,6 @@ class User < ActiveRecord::Base |
| 62 | 61 | question.activate! |
| 63 | 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 | 64 | def deactivate_question(question_id, options) |
| 76 | 65 | question = questions.find(question_id) |
| 77 | 66 | question.deactivate! | ... | ... |
app/models/visitor.rb
| ... | ... | @@ -3,7 +3,7 @@ class Visitor < ActiveRecord::Base |
| 3 | 3 | has_many :questions, :class_name => "Question", :foreign_key => "creator_id" |
| 4 | 4 | has_many :votes, :class_name => "Vote", :foreign_key => "voter_id" |
| 5 | 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 | 7 | has_many :clicks |
| 8 | 8 | has_many :appearances, :foreign_key => "voter_id" |
| 9 | 9 | ... | ... |
app/views/items/edit.html.erb
app/views/items/index.html.erb
| ... | ... | @@ -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 | 0 | \ No newline at end of file |
app/views/items/new.html.erb
app/views/items/show.html.erb
app/views/layouts/items.html.erb
| ... | ... | @@ -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> |
| ... | ... | @@ -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 | 496 | |
| 497 | 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 | 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 | 511 | return error_message.blank? ? [success_message, false] : [error_message, true] |
| 510 | 512 | end |
| 511 | 513 | ... | ... |
spec/models/choice_spec.rb
| ... | ... | @@ -3,14 +3,18 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') |
| 3 | 3 | describe Choice do |
| 4 | 4 | |
| 5 | 5 | it {should belong_to :question} |
| 6 | - it {should belong_to :item} | |
| 6 | + it {should belong_to :creator} | |
| 7 | 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 | 11 | it {should validate_presence_of :question} |
| 12 | + it {should validate_presence_of :creator} | |
| 9 | 13 | |
| 10 | 14 | before(:each) do |
| 11 | 15 | @aoi_clone = Factory.create(:email_confirmed_user) |
| 12 | 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 | 18 | :site => @aoi_clone, |
| 15 | 19 | :creator => @visitor) |
| 16 | 20 | |
| ... | ... | @@ -25,13 +29,6 @@ describe Choice do |
| 25 | 29 | Choice.create!(@valid_attributes) |
| 26 | 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 | 32 | it "should deactivate a choice" do |
| 36 | 33 | choice1 = Choice.create!(@valid_attributes.merge(:data => '1234')) |
| 37 | 34 | choice1.deactivate! |
| ... | ... | @@ -39,12 +36,14 @@ describe Choice do |
| 39 | 36 | end |
| 40 | 37 | |
| 41 | 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 | 48 | end |
| 50 | 49 | |
| ... | ... | @@ -67,4 +66,61 @@ describe Choice do |
| 67 | 66 | @question.reload |
| 68 | 67 | @question.inactive_choices_count.should == prev_inactive + 1 |
| 69 | 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 | 126 | end | ... | ... |
spec/models/item_spec.rb
| ... | ... | @@ -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 | 4 | it {should belong_to :question} |
| 5 | 5 | it {should belong_to :left_choice} |
| 6 | 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 | 19 | end | ... | ... |
spec/models/question_spec.rb
| ... | ... | @@ -112,6 +112,12 @@ describe Question do |
| 112 | 112 | @question_optional_information[:picked_prompt_id].should == saved_prompt_id |
| 113 | 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 | 121 | context "catchup algorithm" do |
| 116 | 122 | before(:all) do |
| 117 | 123 | @catchup_q = Factory.create(:aoi_question) |
| ... | ... | @@ -283,7 +289,6 @@ describe Question do |
| 283 | 289 | rows.first.should include("Record ID") |
| 284 | 290 | rows.first.should include("Record Type") |
| 285 | 291 | rows.first.should_not include("Idea ID") |
| 286 | - puts filename | |
| 287 | 292 | File.delete(filename).should_not be_nil |
| 288 | 293 | |
| 289 | 294 | |
| ... | ... | @@ -300,7 +305,6 @@ describe Question do |
| 300 | 305 | rows = FasterCSV.read(filename) |
| 301 | 306 | rows.first.should include("Idea ID") |
| 302 | 307 | rows.first.should_not include("Skip ID") |
| 303 | - puts filename | |
| 304 | 308 | File.delete(filename).should_not be_nil |
| 305 | 309 | |
| 306 | 310 | end | ... | ... |
spec/models/visitor_spec.rb