Commit 9f0ec712f3369a626f7484d3cd24ef9acfb0e295
1 parent
18da412d
Exists in
master
and in
1 other branch
Rewriting skips model, providing support
Showing
9 changed files
with
124 additions
and
31 deletions
Show diff stats
app/controllers/prompts_controller.rb
@@ -53,9 +53,7 @@ class PromptsController < InheritedResources::Base | @@ -53,9 +53,7 @@ class PromptsController < InheritedResources::Base | ||
53 | @prompt = @question.prompts.find(params[:id]) | 53 | @prompt = @question.prompts.find(params[:id]) |
54 | 54 | ||
55 | time_viewed = params['params']['time_viewed'] | 55 | time_viewed = params['params']['time_viewed'] |
56 | - | ||
57 | visitor_identifier = params['params']['auto'] | 56 | visitor_identifier = params['params']['auto'] |
58 | - | ||
59 | appearance_lookup = params['params']['appearance_lookup'] | 57 | appearance_lookup = params['params']['appearance_lookup'] |
60 | 58 | ||
61 | case direction | 59 | case direction |
@@ -71,6 +69,7 @@ class PromptsController < InheritedResources::Base | @@ -71,6 +69,7 @@ class PromptsController < InheritedResources::Base | ||
71 | respond_to do |format| | 69 | respond_to do |format| |
72 | if successful | 70 | if successful |
73 | #catchup_marketplace_ids = [120, 117, 1, 116] | 71 | #catchup_marketplace_ids = [120, 117, 1, 116] |
72 | + #TODO refactor into question model | ||
74 | if @question.uses_catchup? | 73 | if @question.uses_catchup? |
75 | logger.info("Question #{@question.id} is using catchup algorithm!") | 74 | logger.info("Question #{@question.id} is using catchup algorithm!") |
76 | next_prompt = @question.pop_prompt_queue | 75 | next_prompt = @question.pop_prompt_queue |
@@ -125,12 +124,45 @@ class PromptsController < InheritedResources::Base | @@ -125,12 +124,45 @@ class PromptsController < InheritedResources::Base | ||
125 | authenticate | 124 | authenticate |
126 | logger.info "#{current_user.inspect} is skipping." | 125 | logger.info "#{current_user.inspect} is skipping." |
127 | @question = Question.find(params[:question_id]) | 126 | @question = Question.find(params[:question_id]) |
128 | - @prompt = @question.prompts.find(params[:id], :include => [{ :left_choice => :item }, { :right_choice => :item }]) | 127 | + @prompt = @question.prompts.find(params[:id]) #, :include => [{ :left_choice => :item }, { :right_choice => :item }]) |
128 | + | ||
129 | + time_viewed = params['params']['time_viewed'] | ||
130 | + raise "time_viewed cannot be nil" if time_viewed.nil? | ||
131 | + | ||
132 | + visitor_identifier = params['params']['auto'] | ||
133 | + raise "visitor identifier cannot be nil" if visitor_identifier.nil? | ||
134 | + appearance_lookup = params['params']['appearance_lookup'] | ||
135 | + raise "appearance_lookup cannot be nil" if appearance_lookup.nil? | ||
136 | + | ||
137 | + skip_reason = params['params']['skip_reason'] # optional parameter | ||
129 | 138 | ||
130 | 139 | ||
131 | respond_to do |format| | 140 | respond_to do |format| |
132 | - if @skip = current_user.record_skip(params['params']['auto'], @prompt) | ||
133 | - format.xml { render :xml => @question.picked_prompt.to_xml(:methods => [:left_choice_text, :right_choice_text]), :status => :ok } | 141 | + if @skip = current_user.record_skip(visitor_identifier, appearance_lookup, @prompt, time_viewed, :skip_reason => skip_reason) |
142 | + | ||
143 | + if @question.uses_catchup? | ||
144 | + logger.info("Question #{@question.id} is using catchup algorithm!") | ||
145 | + @next_prompt = @question.pop_prompt_queue | ||
146 | + if @next_prompt.nil? | ||
147 | + logger.info("Catchup prompt cache miss! Nothing in prompt_queue") | ||
148 | + @next_prompt = @question.catchup_choose_prompt | ||
149 | + end | ||
150 | + @question.send_later :add_prompt_to_queue | ||
151 | + else | ||
152 | + @next_prompt = @question.picked_prompt | ||
153 | + end | ||
154 | + | ||
155 | + | ||
156 | + visitor = current_user.visitors.find_or_create_by_identifier(visitor_identifier) | ||
157 | + @a = current_user.record_appearance(visitor, @next_prompt) | ||
158 | + | ||
159 | + appearance_id = Proc.new { |options| options[:builder].tag!('appearance_id', @a.lookup) } | ||
160 | + | ||
161 | + visitor_votes = Proc.new { |options| options[:builder].tag!('visitor_votes', visitor.votes.count(:conditions => {:question_id => @question.id})) } | ||
162 | + visitor_ideas = Proc.new { |options| options[:builder].tag!('visitor_ideas', visitor.items.count) } | ||
163 | + | ||
164 | + | ||
165 | + format.xml { render :xml => @question.picked_prompt.to_xml(:procs => [appearance_id, visitor_votes, visitor_ideas],:methods => [:left_choice_text, :right_choice_text]), :status => :ok } | ||
134 | format.json { render :json => @question.picked_prompt.to_json, :status => :ok } | 166 | format.json { render :json => @question.picked_prompt.to_json, :status => :ok } |
135 | else | 167 | else |
136 | format.xml { render :xml => @skip, :status => :unprocessable_entity } | 168 | format.xml { render :xml => @skip, :status => :unprocessable_entity } |
app/models/user.rb
@@ -45,10 +45,9 @@ class User < ActiveRecord::Base | @@ -45,10 +45,9 @@ class User < ActiveRecord::Base | ||
45 | end | 45 | end |
46 | 46 | ||
47 | 47 | ||
48 | - def record_skip(visitor_identifier, prompt) | 48 | + def record_skip(visitor_identifier, appearance_lookup, prompt, time_viewed, options = {}) |
49 | visitor = visitors.find_or_create_by_identifier(visitor_identifier) | 49 | visitor = visitors.find_or_create_by_identifier(visitor_identifier) |
50 | - question = prompt.question | ||
51 | - visitor.skip!(prompt) | 50 | + visitor.skip!(appearance_lookup, prompt, time_viewed, options) |
52 | end | 51 | end |
53 | 52 | ||
54 | def activate_question(question_id, options) | 53 | def activate_question(question_id, options) |
app/models/visitor.rb
@@ -18,6 +18,7 @@ class Visitor < ActiveRecord::Base | @@ -18,6 +18,7 @@ class Visitor < ActiveRecord::Base | ||
18 | 18 | ||
19 | def vote_for!(appearance_lookup, prompt, ordinality, time_viewed) | 19 | def vote_for!(appearance_lookup, prompt, ordinality, time_viewed) |
20 | @a = Appearance.find_by_lookup(appearance_lookup) | 20 | @a = Appearance.find_by_lookup(appearance_lookup) |
21 | + #make votefor fail if we cant find the appearance | ||
21 | choices = prompt.choices | 22 | choices = prompt.choices |
22 | choice = choices[ordinality] #we need to guarantee that the choices are in the right order (by position) | 23 | choice = choices[ordinality] #we need to guarantee that the choices are in the right order (by position) |
23 | other_choices = choices - [choice] | 24 | other_choices = choices - [choice] |
@@ -37,7 +38,12 @@ class Visitor < ActiveRecord::Base | @@ -37,7 +38,12 @@ class Visitor < ActiveRecord::Base | ||
37 | 38 | ||
38 | end | 39 | end |
39 | 40 | ||
40 | - def skip!(prompt) | ||
41 | - prompt_skip = skips.create!(:prompt => prompt) | 41 | + def skip!(appearance_lookup, prompt, time_viewed, options = {}) |
42 | + @a = Appearance.find_by_lookup(appearance_lookup) | ||
43 | + | ||
44 | + skip_create_options = { :question_id => prompt.question_id, :prompt_id => prompt.id, :skipper_id=> self.id, :time_viewed => time_viewed, :appearance_id => @a.id} | ||
45 | + | ||
46 | + prompt_skip = skips.create!(skip_create_options.merge(options)) | ||
47 | + | ||
42 | end | 48 | end |
43 | end | 49 | end |
@@ -0,0 +1,19 @@ | @@ -0,0 +1,19 @@ | ||
1 | +class CreateSkipsModel < ActiveRecord::Migration | ||
2 | + def self.up | ||
3 | + create_table :skips do |table| | ||
4 | + table.text :tracking | ||
5 | + table.integer :site_id | ||
6 | + table.integer :skipper_id | ||
7 | + table.integer :question_id | ||
8 | + table.integer :prompt_id | ||
9 | + table.integer :appearance_id | ||
10 | + table.integer :time_viewed #msecs | ||
11 | + table.timestamps | ||
12 | + end | ||
13 | + | ||
14 | + end | ||
15 | + | ||
16 | + def self.down | ||
17 | + drop_table :skips | ||
18 | + end | ||
19 | +end |
spec/controllers/prompts_controller_spec.rb
1 | require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') | 1 | require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') |
2 | 2 | ||
3 | describe PromptsController do | 3 | describe PromptsController do |
4 | + def sign_in_as(user) | ||
5 | + @controller.current_user = user | ||
6 | + return user | ||
7 | + end | ||
8 | + # | ||
9 | + before(:each) do | ||
10 | + @aoi_clone = Factory.create(:user) | ||
11 | + sign_in_as(@user = Factory(:email_confirmed_user)) | ||
12 | + @johndoe = Factory.create(:visitor, :identifier => 'johndoe', :site => @aoi_clone) | ||
13 | + @question = Factory.create(:question, :name => 'which do you like better?', :site => @aoi_clone, :creator => @aoi_clone.default_visitor) | ||
14 | + @lc = Factory.create(:choice, :question => @question, :creator => @johndoe, :data => 'hello gorgeous') | ||
15 | + @rc = Factory.create(:choice, :question => @question, :creator => @johndoe, :data => 'goodbye gorgeous') | ||
16 | + @prompt = Factory.create(:prompt, :question => @question, :tracking => 'sample', :left_choice => @lc, :right_choice => @rc) | ||
17 | + | ||
18 | + @visitor = @aoi_clone.visitors.find_or_create_by_identifier("test_visitor_identifier") | ||
19 | + @appearance = @aoi_clone.record_appearance(@visitor, @prompt) | ||
20 | + end | ||
21 | + # | ||
4 | 22 | ||
5 | - def mock_prompt(stubs={}) | ||
6 | - @mock_prompt ||= mock_model(Prompt, stubs) | ||
7 | - end | ||
8 | - | ||
9 | - before(:each) do | ||
10 | - @aoi_clone = Factory.create(:user) | ||
11 | - @question = Factory.create(:question, :site => @aoi_clone, :creator => @aoi_clone.default_visitor) | ||
12 | - end | ||
13 | - | ||
14 | - describe "GET index" do | ||
15 | - it "assigns all prompts as @prompts" do | 23 | +# describe "GET index" do |
24 | +# it "assigns all prompts as @prompts" do | ||
16 | # Question.stub!(:find).with(:all).and_return(@question) | 25 | # Question.stub!(:find).with(:all).and_return(@question) |
17 | # Question.stub!(:prompts).with(:all).and_return([mock_prompt]) | 26 | # Question.stub!(:prompts).with(:all).and_return([mock_prompt]) |
18 | - get :index, :question_id => @question.id | ||
19 | - assigns[:prompts].should == [mock_prompt] | ||
20 | - end | ||
21 | - end | 27 | +# get :index, :question_id => @question.id |
28 | +# assigns[:prompts].should == [@prompt] | ||
29 | +# end | ||
30 | +# end | ||
22 | 31 | ||
23 | describe "GET show" do | 32 | describe "GET show" do |
24 | it "assigns the requested prompt as @prompt" do | 33 | it "assigns the requested prompt as @prompt" do |
25 | -# Question.stub!(:find).with(:all).and_return(@question) | ||
26 | -# Prompt.stub!(:find).with("37").and_return(mock_prompt) | ||
27 | - get :show, :id => "37", :question_id => @question.id | ||
28 | - assigns[:prompt].should equal(mock_prompt) | 34 | + get :show, :id => @prompt.id, :question_id => @question.id |
35 | + assigns[:prompt].should == @prompt | ||
29 | end | 36 | end |
30 | end | 37 | end |
38 | + | ||
39 | + describe "POST skip" do | ||
40 | + it "records a skip, responds with next prompt" do | ||
41 | + post :skip, :id => @prompt.id, :question_id => @question.id, :params => {:auto => @visitor, :time_viewed => 30, :appearance_lookup => @appearance.lookup} | ||
42 | + assigns[:next_prompt].should_not == @prompt | ||
43 | + assigns[:next_prompt].should_not be_nil | ||
44 | + assigns[:a].should_not be_nil | ||
45 | + assigns[:a].should_not == @appearance | ||
46 | + assigns[:skip].should_not be_nil | ||
47 | + end | ||
48 | + end | ||
49 | + | ||
31 | end | 50 | end |
spec/models/user_spec.rb
@@ -47,7 +47,7 @@ describe User do | @@ -47,7 +47,7 @@ describe User do | ||
47 | end | 47 | end |
48 | 48 | ||
49 | it "should be able to record a visitor's skip" do | 49 | it "should be able to record a visitor's skip" do |
50 | - s = @aoi_clone.record_skip("johnnydoe", @prompt) | 50 | + s = @aoi_clone.record_skip("johnnydoe", @appearance.lookup, @prompt, 340) |
51 | end | 51 | end |
52 | 52 | ||
53 | end | 53 | end |
spec/models/visitor_spec.rb
@@ -47,7 +47,7 @@ describe Visitor do | @@ -47,7 +47,7 @@ describe Visitor do | ||
47 | it "should be able to skip a prompt" do | 47 | it "should be able to skip a prompt" do |
48 | #@prompt = @question.prompts.first | 48 | #@prompt = @question.prompts.first |
49 | @prompt.should_not be_nil | 49 | @prompt.should_not be_nil |
50 | - v = @v.skip! @prompt | 50 | + v = @v.skip! @appearance.lookup, @prompt, 304 |
51 | end | 51 | end |
52 | 52 | ||
53 | it "should accurately update score counts after vote" do | 53 | it "should accurately update score counts after vote" do |