Skip to content

Commit 7d6e294

Browse files
committed
Replace Subclasses with Strategies: Step Eight
* Introduce polymorphic association for strategy * Build the strategy when building the root type
1 parent e4809cd commit 7d6e294

File tree

6 files changed

+43
-14
lines changed

6 files changed

+43
-14
lines changed

example_app/app/controllers/questions_controller.rb

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def update
3232

3333
def build_question
3434
@question = type.constantize.new(question_params)
35+
@question.build_submittable
3536
@question.survey = @survey
3637
end
3738

example_app/app/models/question.rb

+4-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ class Question < ActiveRecord::Base
66
validates :type, presence: true, inclusion: QUESTION_TYPES
77
validates :title, presence: true
88

9+
belongs_to :submittable, polymorphic: true
910
belongs_to :survey
1011
has_many :answers
1112

@@ -16,9 +17,9 @@ def most_recent_answer_text
1617
answers.most_recent.text
1718
end
1819

19-
def submittable
20+
def build_submittable
2021
submittable_class = type.sub('Question', 'Submittable').constantize
21-
submittable_class.new(question: self)
22+
self.submittable = submittable_class.new(question: self)
2223
end
2324

2425
def summarize(summarizer)
@@ -30,6 +31,7 @@ def switch_to(type, new_attributes)
3031
attributes = self.attributes.merge(new_attributes)
3132
cloned_attributes = attributes.except('id', 'type', 'submittable_type')
3233
new_question = type.constantize.new(cloned_attributes)
34+
new_question.build_submittable
3335
new_question.id = id
3436

3537
begin
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class AddSubmittableTypeAndIdToQuestions < ActiveRecord::Migration
2+
def change
3+
add_column :questions, :submittable_id, :integer
4+
add_column :questions, :submittable_type, :string
5+
end
6+
end

example_app/db/schema.rb

+7-5
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,15 @@
6767
end
6868

6969
create_table "questions", :force => true do |t|
70-
t.string "title", :null => false
71-
t.string "type", :null => false
72-
t.integer "survey_id", :null => false
73-
t.datetime "created_at", :null => false
74-
t.datetime "updated_at", :null => false
70+
t.string "title", :null => false
71+
t.string "type", :null => false
72+
t.integer "survey_id", :null => false
73+
t.datetime "created_at", :null => false
74+
t.datetime "updated_at", :null => false
7575
t.integer "minimum"
7676
t.integer "maximum"
77+
t.integer "submittable_id"
78+
t.string "submittable_type"
7779
end
7880

7981
create_table "scale_submittables", :force => true do |t|

example_app/spec/factories/application.rb

+14
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@
1010
user
1111
end
1212

13+
factory :multiple_choice_submittable do
14+
end
15+
16+
factory :open_submittable do
17+
end
18+
1319
factory :option do
1420
text 'Hello'
1521
end
@@ -28,17 +34,25 @@
2834
FactoryGirl.build(:option, text: text, question_id: attributes.id)
2935
end
3036
end
37+
38+
submittable factory: :multiple_choice_submittable
3139
end
3240

3341
factory :open_question, class: 'OpenQuestion' do
42+
submittable factory: :open_submittable
3443
end
3544

3645
factory :scale_question, class: 'ScaleQuestion' do
3746
minimum 1
3847
maximum 2
48+
49+
submittable factory: :scale_submittable
3950
end
4051
end
4152

53+
factory :scale_submittable do
54+
end
55+
4256
factory :survey do
4357
sequence(:title) { |n| "Survey #{n}" }
4458
author factory: :user

example_app/spec/models/question_spec.rb

+11-7
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,21 @@
1111

1212
it { should validate_presence_of :title }
1313

14+
it { should belong_to(:submittable) }
1415
it { should belong_to(:survey) }
1516
it { should have_many(:answers) }
1617
end
1718

19+
describe Question, '#build_submittable' do
20+
it 'builds a submittable with its type' do
21+
question = build(:open_question)
22+
23+
question.build_submittable
24+
25+
question.submittable.should be_a(OpenSubmittable)
26+
end
27+
end
28+
1829
describe Question, '#most_recent_answer_text' do
1930
it 'returns the text for the latest answer' do
2031
question = create(:open_question)
@@ -36,13 +47,6 @@
3647
end
3748
end
3849

39-
describe Question, '#submittable' do
40-
it 'instantiates a submittable based on its type' do
41-
question = create(:open_question)
42-
question.submittable.should be_a(OpenSubmittable)
43-
end
44-
end
45-
4650
describe Question, '#summarize' do
4751
it 'builds a summary with the result from the summarizer' do
4852
question = build_stubbed(:question)

0 commit comments

Comments
 (0)