แบบฟอร์มที่ซ้อนกันใน Rails 4 ไม่แสดงผลในมุมมอง

ขออภัยหากได้รับคำตอบแล้ว แต่ฉันไม่พบสิ่งใดที่สามารถช่วยฉันได้ ฉันเป็นมือใหม่กับ Rails ดังนั้นโปรดใช้ความสุภาพ: D

ฉันดึงผมออกโดยพยายามทำให้ฟอร์มที่ซ้อนกันทำงานได้ ฉันแน่ใจว่าฉันมีฟอร์มที่ซ้อนกันซึ่งทำงานโดยใช้ Rails 3 และการสาธิต Railscasts เมื่อปีที่แล้ว แต่ Rails 4 กำลังเอาชนะฉันอยู่

เมื่อดูที่บันทึก แบบสอบถามกำลังถูกเรียกใช้เพื่อดึงข้อมูลสำหรับตารางที่เกี่ยวข้อง แต่ไม่มีการแสดงผลใดในแบบฟอร์ม

ฉันได้อ่านเว็บไซต์หลายแห่งแล้ว แต่ยังไม่มีใครช่วยได้ และฉันไม่รู้ว่าจะเริ่มต้นจากตรงไหน บทความล่าสุดที่ฉันติดตามคือ http://www.createdbypete.com/articles/working-with-nested-forms-and-a-many-to-many-association-in-rails-4/

ยังคงไม่มีอะไรถูกเรนเดอร์ในมุมมอง

ฉันจะเริ่มแก้ไขจุดบกพร่องนี้ได้ที่ไหน บางทีการติดตั้ง Rails ของฉันอาจใช้งานไม่ได้?? แต่ฉันอาจพลาดบางสิ่งที่สำคัญไป

ขอบคุณรอยซ์

แก้ไข - ฉันได้เพิ่มตัวควบคุมบางตัวและมุมมองที่เป็นปัญหาแล้ว

Surveys_controller.rb

class SurveysController < ApplicationController
  before_action :set_survey, only: [:show, :edit, :update, :destroy, :answers]

  # GET /surveys
  # GET /surveys.json
  def index
    @surveys = Survey.all
  end

  # GET /surveys/1
  # GET /surveys/1.json
  def show
  end

  # GET /surveys/new
  def new
    @survey = Survey.new
  end

  # GET /surveys/1/edit
  def edit
  end

  # POST /surveys
  # POST /surveys.json
  def create
    @survey = Survey.new(survey_params)

    respond_to do |format|
      if @survey.save
        format.html { redirect_to @survey, notice: 'Survey was successfully created.' }
        format.json { render :show, status: :created, location: @survey }
      else
        format.html { render :new }
        format.json { render json: @survey.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /surveys/1
  # PATCH/PUT /surveys/1.json
  def update
    respond_to do |format|
      if @survey.update(survey_params)
        format.html { redirect_to @survey, notice: 'Survey was successfully updated.' }
        format.json { render :show, status: :ok, location: @survey }
      else
        format.html { render :edit }
        format.json { render json: @survey.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /surveys/1
  # DELETE /surveys/1.json
  def destroy
    @survey.destroy
    respond_to do |format|
      format.html { redirect_to surveys_url, notice: 'Survey was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  def answers
    @participants = Participant.all
    @questions = @survey.questions
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_survey
      @survey = Survey.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def survey_params
      params.require(:survey).permit(:name,
      :questions_attributes => [:id, :content,
        :answers_attributes => [:id, :content, :participant_id]
      ])
    end
end

participents_controller.rb

class ParticipantsController < ApplicationController
  before_action :set_participant, only: [:show, :edit, :update, :destroy]

  # GET /participants
  # GET /participants.json
  def index
    @participants = Participant.all
  end

  # GET /participants/1
  # GET /participants/1.json
  def show
  end

  # GET /participants/new
  def new
    @participant = Participant.new
  end

  # GET /participants/1/edit
  def edit
  end

  # POST /participants
  # POST /participants.json
  def create
    @participant = Participant.new(participant_params)

    respond_to do |format|
      if @participant.save
        format.html { redirect_to @participant, notice: 'Participant was successfully created.' }
        format.json { render :show, status: :created, location: @participant }
      else
        format.html { render :new }
        format.json { render json: @participant.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /participants/1
  # PATCH/PUT /participants/1.json
  def update
    respond_to do |format|
      if @participant.update(participant_params)
        format.html { redirect_to @participant, notice: 'Participant was successfully updated.' }
        format.json { render :show, status: :ok, location: @participant }
      else
        format.html { render :edit }
        format.json { render json: @participant.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /participants/1
  # DELETE /participants/1.json
  def destroy
    @participant.destroy
    respond_to do |format|
      format.html { redirect_to participants_url, notice: 'Participant was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_participant
      @participant = Participant.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def participant_params
      params.require(:participant).permit(:name)
    end
end

application_controller.rb

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
end

answer.html.erb

<h1><%= @survey.name %> Answers</h1>

<%= form_for(@survey) do |f| %>
  <% @participants.each do |participant| -%>
  <h3><%= participant.name %></h3>
  <table>
    <thead>
      <tr>
        <td>Questions</td>
        <td>Answer</td>
      </tr>
    </thead>
    <tbody>
      <% @questions.each do |question| -%>
      <tr>
        <td><%= question.content %></td>
        <td>
        <%= f.fields_for :questions, question do |q| -%>
          <%= q.fields_for :answers, question.answers.find_or_initialize_by(participant: participant) do |a| -%>
            <%= a.text_area :content %>
            <%= a.hidden_field :participant_id, participant.id %>
          <% end -%>
        <% end -%>
        </td>
      </tr>
      <% end -%>
    </tbody>
  </table>
  <% end -%>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end -%>

person Royceybaby    schedule 14.08.2014    source แหล่งที่มา
comment
คำแนะนำด่วน: โพสต์โค้ดเล็กๆ น้อยๆ ที่นี่ บางทีวิธีการควบคุมและมุมมองนั้นเอง   -  person mylescarrick    schedule 14.08.2014
comment
ไชโย ไมลส์ หวังว่าคงช่วยได้   -  person Royceybaby    schedule 14.08.2014
comment
กรุณาโพสต์เนื้อหาของแบบจำลองการสำรวจ คุณอาจหายไป accept_nested_attributes_for :questions   -  person coorasse    schedule 14.08.2014
comment
แบบฟอร์มที่ซ้อนกันนั้นน่าเกลียด สับสน และเปราะบาง - และคุณต้องจำไว้ว่าต้องทำสิ่งเล็กๆ น้อยๆ มากมายอย่างถูกต้องตลอดทั้งสแต็ก คุณสามารถทำให้สิ่งต่าง ๆ เข้าใจง่ายขึ้นมากและช่วยแยกการเปลี่ยนแปลงโดยใช้อ็อบเจ็กต์แบบฟอร์ม วัตถุแบบฟอร์มแกล้งทำเป็นแบบจำลอง ดังนั้นวัตถุจึงทำงานในลักษณะเดียวกับแบบจำลองเมื่อต้องรับมือกับตัวควบคุมหรือมุมมอง มีผู้เชี่ยวชาญ Railscast เกี่ยวกับเรื่องนี้ หรือดู: stackoverflow.com/questions/25296385/   -  person A Fader Darkly    schedule 14.08.2014
comment
มันดูน่าสนใจ คงต้องอ่านดูแล้วล่ะ   -  person Royceybaby    schedule 14.08.2014


คำตอบ (3)


เมื่อคุณเพิ่งเริ่มใช้งาน Rails ให้ฉันอธิบายว่า Nested Forms ทำงานอย่างไรสำหรับคุณ!

--

ซ้อนกัน

แบบฟอร์ม ที่ซ้อนกัน ไม่ได้ซ้อนกันจริงๆ เลย แต่เป็นแบบฟอร์มที่ เชื่อมโยง

คุณต้องจำไว้ว่า Rails (โดยอาศัยการสร้างบน Ruby) นั้นเป็น เชิงวัตถุ< /em> เฟรมเวิร์ก OOP (การเขียนโปรแกรมเชิงวัตถุ) ไม่ได้เป็นเพียงคำศัพท์ แต่เป็นโครงสร้างหลักพื้นฐานสำหรับแอปพลิเคชันของคุณ และวิธีการป้อนข้อมูล / การดำเนินการ

ปัญหาที่หลายๆ คนมีคือพวกเขาไม่ได้ตระหนักถึงธรรมชาติที่แท้จริงของ Rails และทำให้เกิดความสับสนว่าฟีเจอร์ต่างๆ ของมันทำงานอย่างไร หากคุณพบว่า ทุกสิ่งที่คุณทำใน Rails ควรถูกสร้างขึ้น รอบๆ วัตถุ ชีวิตจะง่ายขึ้นมาก!

ป้อนคำอธิบายรูปภาพที่นี่

--

แบบฟอร์ม

ด้วยเหตุนี้ คุณจึงสามารถเริ่มชื่นชมบทบาทของ objects ทั่วทั้ง Rails ได้ จนถึงระดับที่คุณต้องสร้าง / เรียกใช้อ็อบเจ็กต์สำหรับทุกองค์ประกอบของแอปพลิเคชัน Rails ของคุณ รวมถึงแบบฟอร์มของคุณ:

#app/models/survey.rb
Class Survey < ActiveRecord::Base
   has_many :questions
   accepts_nested_attributes_for :questions
end

#app/controllers/surveys_controller.rb
Class SurveysController < ApplicationController
   def new
       @survey = Survey.new
       @survey.questions.build #-> very important
   end
end

#app/views/surveys/new.html.erb
<%= form_for @survey do |f| %>
   ...
   <%= f.fields_for :questions do |q| %>
      <%= q.text_field :title %>
   <% end %>
   <%= f.submit %>
<% end %>

สิ่งนี้ควรสร้างแบบฟอร์มที่ช่วยให้คุณสามารถส่งข้อมูลเชื่อมโยงไปยังโมเดลลูกของคุณ มีองค์ประกอบสำคัญหลายประการที่ต้องพิจารณา:

  1. คุณต้องรวม accepts_nested_attributes_for ในโมเดล "พาเรนต์" ของคุณ
  2. คุณต้อง build วัตถุเชื่อมโยงของคุณ
  3. คุณต้องเติมแบบฟอร์มของคุณด้วยวัตถุสัมพันธ์

โดยการปฏิบัติตามรูปแบบง่ายๆ นี้ คุณจะสามารถเติมข้อมูลแบบฟอร์มซ้อนที่คุณต้องการแสดงในมุมมองได้

person Richard Peck    schedule 14.08.2014
comment
ขอบคุณ Rich ฉันพลาด @survey.questions.build แค่ต้องหาคำตอบว่าทำไมโครงการหลักของฉันถึงไม่ทำงานตอนนี้! ปัญหาเดียวกัน. - person Royceybaby; 14.08.2014
comment
ไม่มีปัญหา - โปรเจ็กต์หลักของคุณมีปัญหาอะไร บางทีเราอาจแก้ไขมันได้? - person Richard Peck; 14.08.2014
comment
ปัญหาเดียวกัน Rich แบบฟอร์มไม่แสดงแอตทริบิวต์ที่ซ้อนกัน โค้ดด้านบนเป็นความพยายามค้นหาว่าทำไมมันถึงใช้งานไม่ได้ ได้ทำสิ่งเดียวกันทุกประการในโปรเจ็กต์หลักแต่ไม่แสดงผล - person Royceybaby; 14.08.2014

ลองใช้รหัสต่อไปนี้:

<%= f.fields_for :questions do |q| -%>
      <%= q.fields_for :answers, q.object.answers.find_or_initialize_by(participant: f.object.participant) do |a| -%>
        <%= a.text_area :content %>
        <%= a.hidden_field :participant_id, participant.id %>
      <% end -%>
    <% end -%>

และตรวจสอบให้แน่ใจว่าคุณเรนเดอร์เป็น answers.html.erb คุณมี accepts_nested_attributes_for :questions ในไฟล์ survey.rb และ accepts_nested_attributes_for :answers ในไฟล์ question.rb

person Mohamed Yakout    schedule 14.08.2014

คุณได้รับ Accepts_nested_attributes_for :question ในรูปแบบการสำรวจของคุณหรือไม่? และเช่นเดียวกันสำหรับโมเดลคำตอบ?

person Ralph King    schedule 14.08.2014