ben
OMÜ , Bilgisayar Mühendisliği, 13'
27 Kasım 2015 Cuma
nested form
Railse nested form yapısını oğrenmek amaçlı, çoktan seçmeli soru hazırlamak için başlayalım:
$rails new nested
$bundle
model yapımız , sınav tablosu, soru tablosu ve şeçenek tablosu, bunlar birbirine has_many ile bağlı olacak
$rails g scaffold exam name:text
$rails g model question content:text exam_id:integer
$rails g model choice content:text question_id:integer
$rake db:migrate
exam.rb
has_many :questions, :dependent=>destroy
accepts_nested_attributes_for :questions, allow_destroy: true
question.rb:
belongs_to :exam
has_many :choices, :dependent=>destroy
choice.rb
belongs_to :questions
exams_controller.rb
def new
@exam = Exam.new
3.times{ @exam.questions.build }
end
view/exams/_form.html.erb
<%= form_for(@exam) do |f| %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div>
<%= f.fields_for :questions do |build|%>
<br/>
<fieldset>
<%= build.label :content, "Soru:"%><br/>
<%= build.text_area :content, :row=>3 %>
</fieldset>
<%end%>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
exam_controller.rb
def exam_params
params.require(:exam).permit(:name, questions_attributes: [:id ,:content])
end
view/exam/show.html.erb
<p>
<strong>Name:</strong>
<%=h @exam.name %>
</p>
<ol>
<% for question in @exam.questions %>
<li><%=h question.content%></li>
<%end%>
</ol>
sınav ve sorularımızı kaydedilim.
Peki sorulardan birisini boş bırakırsak nasıl olcak?
Boş bir soru ekledi, bunun onune geçmek için;
exam.rb
accepts_nested_attributes_for :questions, :reject_if=>lambda {|a| a[:content].blank?}
Sınavlarımızı silebiliyoruz, fakat sınavı silmeden soruyu silmek istersek;
exam_controller.rb
def update:
if @exam.update_attributes(exam_params)
view/exams/_form.html.erb
<%= build.label :content, "Soru:"%><br/>
<%= build.text_area :content, :row=>3 %></br>
<%=build.check_box :_destroy%>
<%=build.label :_destroy, "Soruyu Sil"%>
exam.rb
accepts_nested_attributes_for :questions, :reject_if=>lambda {|a| a[:content].blank?}, allow_destroy: true
def exam_params
params.require(:exam).permit(:name, questions_attributes: [:id ,:content,:_destroy])
end
Bu sorulara birde cevap eklememiz lazım:
question.rb
belongs_to :exam
has_many :choices, dependent: :destroy
accepts_nested_attributes_for :choices, :reject_if=>lambda {|a| a[:content].blank?}, allow_destroy: true
_form.html de bulunan soru alanlarını başka bir html sayfasına taşiyalım:
form_html.erb
<div>
<%= f.fields_for :questions do |build|%>
<br/>
<%= render 'question_fields', f:build%>
<%end%>
</div>
_question_fields.html.erb olusturup düzenleyelim
<fieldset>
<%= f.label :content, "Soru:"%><br/>
<%= f.text_area :content, :row=>3 %></br>
<%= f.check_box :_destroy%>
<%= f.label :_destroy, "Soruyu Sil"%>
<%= f.fields_for :choices do |build|%>
<br/>
<%= render 'choice_fields', f:build%>
<%end%>
</fieldset>
_choice_fields.html.erb oluşturup düzenleyelim
<%= f.label :content, "Cevap:"%>
<%= f.text_field :content %>
<%= f.check_box :_destroy%>
<%= f.label :_destroy, "Seçeneği Sil"%>
Cevap alanlarımızıda oluşturduk
Kaydet alanına tıkladığımızda kaydetmiyor, ufak bir düzenleme daha..
exam_controller.rb
def exam_params
params.require(:exam).permit(:name, questions_attributes: [:id ,:content,:_destroy, choices_attributes: [:id ,:content,:_destroy]])
end
yeni sınav oluşturalım
Show sayfamız:
proje burada..