简体   繁体   English

应用到动态创建的嵌套表单时处理单选按钮

[英]Handling radio buttons when applying to a nested form created dynamically

I have an app where users can create their own forms and then apply them to their own clients 我有一个应用程序, users可以在其中创建自己的forms ,然后将其应用于自己的clients

The forms are created dynamically, meaning users can add as many questions they want, and each question has many choices (think of a survey structure). forms是动态创建的,这意味着用户可以添加他们想要的尽可能多的questions ,并且每个问题都有很多choices (例如调查结构)。

So far so good, now I'm struggling when applying the forms, specifically getting the answers saved, persisted and showing properly when rendering the edit view. 到目前为止,到目前为止,我在应用表格时一直在挣扎,尤其是在保存answers保留answers并在呈现edit视图时正确显示answers

When rendering the edit view, each question has their choices multiplied by how many questions/answers the answered_form has (I don't know exactly which of them, I am guessing here). 呈现edit视图时,每个问题的选择都将乘以Answered_form有多少个问题/答案(我不知道确切是哪个,我在这里猜测)。

Answers are persisted to database, although each question has their choices multiplied, the selected answer is checked and is checked in the collection of the original answer. Answers会保留在数据库中,尽管每个问题的选择都会成倍增加,但选中的答案会被检查并在原始答案的集合中被选中。 (answer one checked in the first 3 choices, answer two in the second 3 choices, answer three in the third 3 choices and answer four in the forth 3 choices) (回答前三个选择中的一个,第二三个选择中的两个,第三三个选择中的三个,第四三个选择中的四个)

I've read 2 similar questions here in SO, RoR nested attributes produces duplicates when edit , and Nested form update action producing duplicate results , but I already have the :id in strong parameters (you can see it in the code below). 我已经在SO中阅读了2个类似的问题, RoR的嵌套属性在edit时会产生重复 ,而嵌套的表单更新操作会产生重复的结果 ,但是我已经在强参数中使用了:id (您可以在下面的代码中看到它)。

I want to make myself clear here: creating the form, with nested question and nested choices is working perfectly fine, and also editing the created form. 我想在这里澄清一下: 使用嵌套的问题和嵌套的选项创建表单工作得很好,并且还可以编辑创建的表单。 The struggle is when USING, ANSWERING or APPLYING it in the APP. 困难在于何时在应用程序使用,回答或应用它

Code: 码:

_form.html.erb: _form.html.erb:

<%= form_for [@child, @answered_form] do |f| %>

  <%= f.hidden_field :form_id %>
  <%= f.hidden_field :child_id %>

  <div class="answered_form">

  <h1><%= @form.f_title %></h1>
  <h3><%= @form.f_description %></h3>
  <br>
  <% questions = @form.questions %>
  <% i = 1 %>
  <% questions.each do |question| %>

    <%= i.to_s + ". " %><%= question.q_title %>
    <br />
    <% choices = question.choices %>

    <%= f.fields_for :answers do |a| %>

      <% choices.each do |choice| %>

        <%= a.radio_button :a_content, choice.c_description %> 
        <%= a.label :a_content, choice.c_description, :value => choice.c_description, class: 'no-margin' %>
        <br />

      <% end %>

    <% end %>

     <br />
     <% i += 1 %>
  <% end %>

</div>

<div class="text-center">
  <%= f.submit yield(:button_text), class: "btn btn-primary btn-lg" %>
</div>

<% end %>

answered_forms_controller.rb: answer_forms_controller.rb:

class AnsweredFormsController < ApplicationController
  before_action :correct_answered_form,  only: [:edit, :update, :destroy]

  def new
    @child = current_user.children.find(params[:child_id])
    @form = current_user.forms.find(params[:form_id])
    @answered_form = @child.answered_forms.new(form_id: params[:form_id])
    @answered_form.answers.build
  end

  def create
    @answered_form = AnsweredForm.create(answered_form_params)
    if @answered_form.save
      flash[:success] = "New survey " + @answered_form.form.f_title + " applied to patient!"
      redirect_to current_user.children.find(params[:child_id])
    else
      render 'new'
    end
  end

  def edit
    @child = current_user.children.find(params[:child_id])
    @form = current_user.forms.find(params[:form_id])
  end

  def update
    if @answered_form.update_attributes(answered_form_params)
      flash[:success] = "Survey updated!"
      redirect_to @answered_form.child
    else
      render 'edit'
    end
  end

  def show
  end

  def destroy
    @child = current_user.children.find(params[:child_id])
    @form = current_user.forms.find(params[:form_id])
    @answered_form.destroy
    redirect_to :back
  end

  private

    # Strong params for creating and updating forms
    def answered_form_params
      params.require(:answered_form).permit(:form_id, :child_id, answers_attributes: [:id, :a_content, :a_boolean, :_destroy, :choice_id])
    end

    # Confirms the correct answered_form
    def correct_answered_form
      @answered_form = AnsweredForm.find(params[:id])
    end

end

Logs: POST: 日志: POST:

Started POST "/children/1-juan-gomez-pereira/answered_forms" for ::1 at 2016-07-08 11:55:01 -0400
Processing by AnsweredFormsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"hFrRfEwVG4XSkdbPwrohm1QEQ0FtE/as3sM2Fj3Av3reVHJxZBVKPeuAeD713H7gVyZn7eppnULDhLJQz+EBeg==", "answered_form"=>{"form_id"=>"1", "child_id"=>"1", "answers_attributes"=>{"0"=>{"a_content"=>"Bajo"}, "1"=>{"a_content"=>"Sí"}, "2"=>{"a_content"=>"Derecha"}, "3"=>{"a_content"=>"Pesado"}}}, "commit"=>"Aplicar", "child_id"=>"1-juan-gomez-pereira"}

PATCH: 补丁:

Started PATCH "/children/1-juan-gomez-pereira/answered_forms/3" for ::1 at 2016-07-08 11:55:54 -0400
Processing by AnsweredFormsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"oGdqgUR95HMkMff40Gq1zWar/CH64F0jsN3oRHT1q/H6acmMbH21yx0gWQnnDOq2ZYnYjX2aNs2tmmwChtQV8Q==", "answered_form"=>{"form_id"=>"1", "child_id"=>"1", "answers_attributes"=>{"0"=>{"a_content"=>"Bajo", "id"=>"9"}, "1"=>{"a_content"=>"Bajo", "id"=>"10"}, "2"=>{"a_content"=>"Bajo", "id"=>"11"}, "3"=>{"a_content"=>"Confuso", "id"=>"12"}, "4"=>{"a_content"=>"No", "id"=>"9"}, "5"=>{"a_content"=>"Sí", "id"=>"10"}, "6"=>{"a_content"=>"Confuso", "id"=>"11"}, "7"=>{"a_content"=>"Confuso", "id"=>"12"}, "8"=>{"a_content"=>"Confuso", "id"=>"9"}, "9"=>{"a_content"=>"Izquierda", "id"=>"10"}, "10"=>{"a_content"=>"Confuso", "id"=>"11"}, "11"=>{"a_content"=>"Izquierda", "id"=>"12"}, "12"=>{"a_content"=>"Liviano", "id"=>"9"}, "13"=>{"a_content"=>"Liviano", "id"=>"10"}, "14"=>{"a_content"=>"Pesado", "id"=>"11"}, "15"=>{"a_content"=>"Liviano", "id"=>"12"}}}, "commit"=>"Actualizar", "child_id"=>"1-juan-gomez-pereira", "id"=>"3"}

I noticed that when POST, the id for answer is not passed as a parameter. 我注意到在POST时,答案的id没有作为参数传递。 If I check the console, I can see that answer was created properly. 如果我检查控制台,则可以看到答案已正确创建。

I think this line could be the problem 我认为这可能是问题所在

<% choices.each do |choice| %>

If you have built question.answers , you can iterate on them only using f.fields_for :answers and skip the above line. 如果您已经构建了question.answers ,则只能使用f.fields_for :answers对其进行迭代,并跳过上面的行。 I assume choices are not much different from answers . 我认为choicesanswers没有太大不同。

Please clear me if i am wrong. 如果我错了,请告诉我。

So the problem was in this line of the code: 所以问题出在这行代码:

<%= f.fields_for :answers do |a| %>

fields_for helper generates fields for the entire collection of the object for whom your are calling it. fields_for辅助函数会为您要为其调用的对象的整个集合生成字段。

In this case, @answered_form had 4 answers after creating it, so when calling fields_for in edit, it was generating 4 fields set for each question. 在这种情况下, @answered_form创建后有4个answers ,因此在编辑中调用fields_for时,它将为每个问题生成4个字段。

To solve this, you need to specify a collection that fits your needs and pass it through the fields_for helper: 为了解决这个问题,您需要指定一个适合您需求的集合,并将其通过fields_for助手:

<%= f.fields_for :answers, ANSWERS_COLLECTION do |a| %>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM