설문조사 사례로 살펴보는 모델 관계에 따라 중첩하는 입력 폼
rails new surveyform
rails g scaffold survey name:string
rake db:migrate
rails g model question content:text survey:references
rake db:migrate
- dependent 옵션을 :destory로 설정하여 survey를 삭제하면 question 도 삭제합니다.
- accepts_nested_attributes_for 는 survey 에서 question을 여러개 만들어서 붙일 수 있습니다.
/app/models/survey.rb
class Survey < ActiveRecord::Base
has_many :questions, :dependent => :destroy
accepts_nested_attributes_for :questions
end
fields_for 는 questions 에 대한 폼을 생성합니다.
/app/views/survey/_form.html.erb
<div>
<%= f.fields_for :questions do |builder| %>
<p>
<%= builder.label :content, "Question" %><br />
<%= builder.text_area :content, :rows => 3 %>
</p>
<% end %>
</div>
/app/controllers/surveys_controller.rb
# GET /surveys/new
def new
@survey = Survey.new
3.times { @survey.questions.build }
end
...
def survey_params
params.require(:survey).permit(:name, questions_attributes: [:id, :content])
end
제목: 시청율 조사
내용:
-
시청하는 티비 프로그램의 수는 몇편입니까?
-
어떤 드라마를 좋아합니까?
/app/views/survey/show.html.erb
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= @survey.name %>
</p>
<ol>
<% for question in @survey.questions %>
<li><%= question.content %></li>
<% end %>
</ol>
<%= link_to 'Edit', edit_survey_path(@survey) %> |
<%= link_to "Destroy", @survey, :confirm => 'Are you sure?', :method => :delete %> |
<%= link_to 'Back', surveys_path %>
'시청하는 티비 프로그램의 수는 몇편입니까?'을 '시청하는 서울방송 프로그램의 수는 몇편입니까?'로 수정
기존의 문항을 삭제하지 못합니다. 설문조사를 새로 만들 때 비어있는 문항을 제외합니다.
/app/models/survey.rb
class Survey < ActiveRecord::Base
has_many :questions, :dependent => :destroy
accepts_nested_attributes_for :questions, reject_if: proc { |a| a['content'].blank? }
end
/app/views/survey/_form.html.erb
<div class="field">
<%= f.fields_for :questions do |builder| %>
<p>
<%= builder.label :content, "Question" %><br />
<%= builder.text_area :content, :rows => 3 %>
<%= builder.check_box :_destroy %>
<%= builder.label :_destroy, "Remove Question" %>
</p>
<% end %>
</div>
/app/models/survey.rb
class Survey < ActiveRecord::Base
has_many :questions, :dependent => :destroy
accepts_nested_attributes_for :questions, reject_if: proc { |a| a['content'].blank? }
end
/app/controllers/surveys_controller.rb
def survey_params
params.require(:survey).permit(:name, questions_attributes: [:id, :content, :_destroy])
end
rails g model answer content:string question:references
rake db:migrate
설문조사(survey)에 문항(question)을 추가했듯이 문항(question)에 달릴 선택지(answer)에 대해 question 모델 수정
/app/models/question.rb
class Question < ActiveRecord::Base
belongs_to :survey
has_many :answers, :dependent => :destroy
accepts_nested_attributes_for :answers, reject_if: proc { |a| a['content'].blank? }, allow_destroy: true
end
/app/views/surveys/_question_fields.html.erb 파일을 새로 만듭니다.
<p>
<%= f.label :content, "Question" %><br />
<%= f.text_area :content, rows: 3 %><br />
<%= f.check_box :_destroy %>
<%= f.label :_destroy, "Remove Question" %>
</p>
/app/views/surveys/_form.html.erb
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.fields_for :questions do |builder| %>
<%= render 'question_fields', f: builder %>
<% end %>
</div>
/app/views/surveys/_answer_fields.html.erb 파일을 새로 만듭니다.
<p>
<%= f.label :content, "Answer" %>
<%= f.text_field :content %>
<%= f.check_box :_destroy %>
<%= f.label :_destroy, "Remove" %>
</p>
/app/views/surveys/_question_fields.html.erb
<p>
<%= f.label :content, "Question" %><br />
<%= f.text_area :content, rows: 3 %><br />
<%= f.check_box :_destroy %>
<%= f.label :_destroy, "Remove Question" %>
</p>
<%= f.fields_for :answers do |builder| %>
<%= render 'answer_fields', f: builder %>
<% end %>
/app/controllers/surveys_controller.rb
# GET /surveys/new
def new
@survey = Survey.new
3.times do
question = @survey.questions.build
4.times { question.answers.build }
end
end
...
def survey_params
params.require(:survey).permit(:name,
questions_attributes: [
:id, :content, :_destroy,
answers_attributes: [
:id, :content, :_destroy
]
]
)
end
제목: 사이트 만족도 조사
문항: 최근에 레일스를 사용해본 적이 있습니까?
선택지:
자주
가끔
글쎄요
전혀 사용하지 않아요