Skip to content

Commit

Permalink
Replace Subclasses with Strategies: Step Seven
Browse files Browse the repository at this point in the history
* Convert strategies to ActiveRecord subclasses
* Create empty tables for strategies
  • Loading branch information
jferris committed Feb 7, 2013
1 parent 7507598 commit e4809cd
Show file tree
Hide file tree
Showing 12 changed files with 76 additions and 31 deletions.
10 changes: 4 additions & 6 deletions example_app/app/models/multiple_choice_submittable.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
class MultipleChoiceSubmittable
def initialize(question)
@question = question
end
class MultipleChoiceSubmittable < ActiveRecord::Base
has_one :question, as: :submittable

def breakdown
total = answers.count
Expand All @@ -28,10 +26,10 @@ def score(text)
private

def answers
@question.answers
question.answers
end

def options
@question.options
question.options
end
end
8 changes: 3 additions & 5 deletions example_app/app/models/open_submittable.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
class OpenSubmittable
def initialize(question)
@question = question
end
class OpenSubmittable < ActiveRecord::Base
has_one :question, as: :submittable

def breakdown
text_from_ordered_answers = answers.order(:created_at).pluck(:text)
Expand All @@ -15,6 +13,6 @@ def score(text)
private

def answers
@question.answers
question.answers
end
end
7 changes: 4 additions & 3 deletions example_app/app/models/question.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ def most_recent_answer_text
end

def submittable
submittable_class_name = type.sub('Question', 'Submittable')
submittable_class_name.constantize.new(self)
submittable_class = type.sub('Question', 'Submittable').constantize
submittable_class.new(question: self)
end

def summarize(summarizer)
Expand All @@ -28,7 +28,8 @@ def summarize(summarizer)

def switch_to(type, new_attributes)
attributes = self.attributes.merge(new_attributes)
new_question = type.constantize.new(attributes.except('id', 'type'))
cloned_attributes = attributes.except('id', 'type', 'submittable_type')
new_question = type.constantize.new(cloned_attributes)
new_question.id = id

begin
Expand Down
10 changes: 4 additions & 6 deletions example_app/app/models/scale_submittable.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
class ScaleSubmittable
def initialize(question)
@question = question
end
class ScaleSubmittable < ActiveRecord::Base
has_one :question, as: :submittable

def breakdown
sprintf('Average: %.02f', answers.average('text'))
Expand All @@ -12,12 +10,12 @@ def score(text)
end

def steps
(@question.minimum..@question.maximum).to_a
(question.minimum..question.maximum).to_a
end

private

def answers
@question.answers
question.answers
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class CreateMultipleChoiceSubmittables < ActiveRecord::Migration
def change
create_table :multiple_choice_submittables do |table|
table.timestamps null: false
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class CreateOpenSubmittables < ActiveRecord::Migration
def change
create_table :open_submittables do |table|
table.timestamps null: false
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class CreateScaleSubmittables < ActiveRecord::Migration
def change
create_table :scale_submittables do |table|
table.timestamps null: false
end
end
end
17 changes: 16 additions & 1 deletion example_app/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.

ActiveRecord::Schema.define(:version => 20130116211337) do
ActiveRecord::Schema.define(:version => 20130131205918) do

create_table "answers", :force => true do |t|
t.integer "completion_id", :null => false
Expand Down Expand Up @@ -48,6 +48,16 @@
add_index "invitations", ["survey_id"], :name => "index_invitations_on_survey_id"
add_index "invitations", ["token"], :name => "index_invitations_on_token", :unique => true

create_table "multiple_choice_submittables", :force => true do |t|
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end

create_table "open_submittables", :force => true do |t|
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end

create_table "options", :force => true do |t|
t.integer "question_id", :null => false
t.string "text", :null => false
Expand All @@ -66,6 +76,11 @@
t.integer "maximum"
end

create_table "scale_submittables", :force => true do |t|
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end

create_table "surveys", :force => true do |t|
t.string "title", :null => false
t.datetime "created_at", :null => false
Expand Down
12 changes: 8 additions & 4 deletions example_app/spec/models/multiple_choice_submittable_spec.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
describe MultipleChoiceSubmittable do
it { should have_one(:question) }
end

describe MultipleChoiceSubmittable, '#breakdown' do
it 'returns a percentage breakdown' do
survey = create(:survey)
Expand All @@ -6,7 +10,7 @@
options_texts: %w(Blue Red),
survey: survey
)
submittable = MultipleChoiceSubmittable.new(question)
submittable = MultipleChoiceSubmittable.new(question: question)
taker = AnswerCreator.new(survey)
taker.answer question, 'Red'
taker.answer question, 'Blue'
Expand All @@ -19,22 +23,22 @@
describe MultipleChoiceSubmittable, '#options_for_form' do
it 'adds empty options when none are present' do
question = build_stubbed(:multiple_choice_question, options: [])
submittable = MultipleChoiceSubmittable.new(question)
submittable = MultipleChoiceSubmittable.new(question: question)
submittable.options_for_form.count.should == 3
end

it 'leaves existing options alone' do
options = [Option.new(text: 'hey'), Option.new(text: 'hello')]
question = build_stubbed(:multiple_choice_question, options: options)
submittable = MultipleChoiceSubmittable.new(question)
submittable = MultipleChoiceSubmittable.new(question: question)
submittable.options_for_form.map(&:text).should match_array(['hey', 'hello'])
end
end

describe MultipleChoiceSubmittable, '#score' do
it 'returns the score for the option with the given text' do
question = build_stubbed(:multiple_choice_question)
submittable = MultipleChoiceSubmittable.new(question)
submittable = MultipleChoiceSubmittable.new(question: question)
question.options.target.stubs(score: 2)

result = submittable.score('two')
Expand Down
8 changes: 6 additions & 2 deletions example_app/spec/models/open_submittable_spec.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
describe OpenSubmittable do
it { should have_one(:question) }
end

describe OpenSubmittable, '#breakdown' do
it 'returns all answers' do
survey = create(:survey)
question = create(:open_question, survey: survey)
submittable = OpenSubmittable.new(question)
submittable = OpenSubmittable.new(question: question)
taker = AnswerCreator.new(survey)

taker.answer question, 'Hey'
Expand All @@ -16,7 +20,7 @@
describe OpenSubmittable, '#score' do
it 'returns zero' do
question = build_stubbed(:open_question)
submittable = OpenSubmittable.new(question)
submittable = OpenSubmittable.new(question: question)

result = submittable.score('anything')

Expand Down
4 changes: 3 additions & 1 deletion example_app/spec/models/question_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

describe Question, '#submittable' do
it 'instantiates a submittable based on its type' do
question = OpenQuestion.new
question = create(:open_question)
question.submittable.should be_a(OpenSubmittable)
end
end
Expand All @@ -63,6 +63,7 @@

new_question.errors.should be_empty
new_question.should be_a(ScaleQuestion)
new_question.submittable.should be_a(ScaleSubmittable)
new_question.minimum.should eq 1
new_question.maximum.should eq 2
Question.count.should eq 1
Expand All @@ -75,6 +76,7 @@

new_question.errors.should be_present
new_question.should be_a(ScaleQuestion)
new_question.submittable.should be_a(ScaleSubmittable)
new_question.minimum.should eq 1
end
end
10 changes: 7 additions & 3 deletions example_app/spec/models/scale_submittable_spec.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
describe ScaleSubmittable do
it { should have_one(:question) }
end

describe ScaleSubmittable, '#breakdown' do
it 'returns the average' do
survey = create(:survey)
question = create(:scale_question, minimum: 0, maximum: 10, survey: survey)
submittable = ScaleSubmittable.new(question)
submittable = ScaleSubmittable.new(question: question)
taker = AnswerCreator.new(survey)
taker.answer question, 6
taker.answer question, 6
Expand All @@ -15,7 +19,7 @@
describe ScaleSubmittable, '#score' do
it 'returns the integer value of the text' do
question = build_stubbed(:scale_question)
submittable = ScaleSubmittable.new(question)
submittable = ScaleSubmittable.new(question: question)

result = submittable.score('5')

Expand All @@ -26,7 +30,7 @@
describe ScaleSubmittable, '#steps' do
it 'returns all numbers starting at the minimum and ending at the maximum' do
question = build_stubbed(:scale_question, minimum: 2, maximum: 5)
submittable = ScaleSubmittable.new(question)
submittable = ScaleSubmittable.new(question: question)
submittable.steps.should eq [2, 3, 4, 5]
end
end

0 comments on commit e4809cd

Please sign in to comment.