Rails 4中的嵌套表单未在视图中呈现

时间:2014-08-14 07:47:44

标签: ruby-on-rails nested-forms

道歉,如果这已经得到回答,但我找不到任何可以帮助我的事情。我是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

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

3 个答案:

答案 0 :(得分:2)

正如您对Rails的新认识一样,让我解释嵌套表单如何为您服务!

-

<强>嵌套

嵌套表单实际上并不是嵌套的 - 它们是关联表单。

你必须记住Rails(由于构建在Ruby上)是一个object orientated框架。 OOP(面向对象的编程)不仅仅是一个流行语 - 它是您应用程序的基本核心结构。如何输入/执行。

许多人遇到的问题是他们没有意识到Rails的本质,因而对其许多功能的工作方式感到困惑。如果你理解你在Rails中所做的一切都应该围绕对象构建,那么生活会变得更加简单!

enter image description here

-

<强>表格

考虑到这一点,你可以开始认识到object在整个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. 您需要在父母&#34;中添加accepts_nested_attributes_for。模型
  2.   
  3. 您需要build您的关联对象
  4.   
  5. 您需要使用相对对象填充表单
  6.   

通过遵循这个简单的模式,您将能够填充您希望在视图中显示的嵌套表单

答案 1 :(得分:0)

您的调查模型中是否有Accept_nested_attributes_for:问题?答案模型也一样吗?

答案 2 :(得分:0)

尝试使用以下代码:

<%= 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.erbaccepts_nested_attributes_for :questions文件中有survey.rbaccepts_nested_attributes_for :answers文件中有question.rb