Skip to content

Commit 5f4a14f

Browse files
committed
Replace Subclasses with Strategies: Step Fifteen
* Simplify type switching
1 parent c6f0e54 commit 5f4a14f

File tree

4 files changed

+25
-42
lines changed

4 files changed

+25
-42
lines changed

example_app/app/controllers/types_controller.rb

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,25 @@
11
class TypesController < ApplicationController
22
def new
33
@question = Question.find(params[:question_id])
4-
assign_type
5-
@new_question = Question.new
6-
@new_question.build_submittable(type, {})
4+
@question.build_submittable(type, {})
75
end
86

97
def create
108
@question = Question.find(params[:question_id])
11-
@new_question = @question.switch_to(
9+
@question.switch_to(
1210
type,
13-
question_params,
1411
submittable_attributes
1512
)
1613

17-
if @new_question.errors.empty?
14+
if @question.errors.empty?
1815
redirect_to @question.survey
1916
else
20-
assign_type
2117
render 'new'
2218
end
2319
end
2420

2521
private
2622

27-
def assign_type
28-
@new_type = type.underscore
29-
end
30-
31-
def question_params
32-
params[:question].except(:submittable_attributes)
33-
end
34-
3523
def submittable_attributes
3624
params[:question][:submittable_attributes] || {}
3725
end

example_app/app/models/question.rb

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,21 +34,14 @@ def summarize(summarizer)
3434
Summary.new(title, value)
3535
end
3636

37-
def switch_to(type, new_attributes, submittable_attributes)
38-
attributes = self.attributes.merge(new_attributes)
39-
cloned_attributes = attributes.except('id', 'type', 'submittable_type')
40-
new_question = Question.new(cloned_attributes)
41-
new_question.build_submittable(type, submittable_attributes)
42-
new_question.id = id
43-
44-
begin
45-
Question.transaction do
46-
destroy
47-
new_question.save!
37+
def switch_to(type, attributes)
38+
old_submittable = submittable
39+
build_submittable type, attributes
40+
41+
transaction do
42+
if save
43+
old_submittable.destroy
4844
end
49-
rescue ActiveRecord::RecordInvalid
5045
end
51-
52-
new_question
5346
end
5447
end

example_app/app/views/types/new.html.erb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
<%= simple_form_for(
2-
@new_question,
2+
@question,
33
as: :question,
4-
url: question_types_path(@question)
4+
url: question_types_path(@question),
5+
method: :post
56
) do |form| -%>
67

78
<%= form.hidden_field :submittable_type %>
89
<%= render(
9-
"#{@new_type}s/#{@new_type}_form",
10-
question: @new_question,
10+
"#{@question.submittable.to_partial_path}_form",
11+
submittable: @question.submittable,
1112
form: form
1213
) %>
1314
<%= form.submit 'Change Type' %>

example_app/spec/models/question_spec.rb

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,26 +65,27 @@
6565
it 'changes the question type and deletes the old question when valid' do
6666
question = create(:open_question)
6767

68-
new_question = question.switch_to(
68+
question.switch_to(
6969
'ScaleQuestion',
70-
{},
71-
{ minimum: 1, maximum: 2 })
70+
{ minimum: 1, maximum: 2 }
71+
)
7272

73-
new_question.errors.should be_empty
74-
submittable = new_question.submittable
73+
question.errors.should be_empty
74+
submittable = question.submittable
7575
submittable.should be_a(ScaleSubmittable)
7676
submittable.minimum.should eq 1
7777
submittable.maximum.should eq 2
7878
Question.count.should eq 1
79+
OpenSubmittable.count.should eq 0
7980
end
8081

8182
it 'leaves the question alone when the new attributes are invalid' do
8283
question = create(:open_question)
8384

84-
new_question = question.switch_to('ScaleQuestion', {}, { minimum: 1 })
85+
question.switch_to('ScaleQuestion', { minimum: 1 })
8586

86-
new_question.errors.should be_present
87-
new_question.submittable.should be_a(ScaleSubmittable)
88-
new_question.submittable.minimum.should eq 1
87+
question.errors.should be_present
88+
question.submittable.should be_a(ScaleSubmittable)
89+
question.submittable.minimum.should eq 1
8990
end
9091
end

0 commit comments

Comments
 (0)