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..