【问题标题】:Rails cocoon nested form only receiving one first nested attributeRails 茧嵌套形式仅接收一个第一个嵌套属性
【发布时间】:2016-01-18 16:33:54
【问题描述】:

我正在尝试在我的 rails 4 应用程序中构建一个包含嵌套资源的表单。我正在使用茧宝石。每个步骤都有子步骤,我希望用户可以根据自己的需要向表单中添加尽可能多的子步骤。

步骤.rb

class Step < ActiveRecord::Base
  has_many :substeps
  accepts_nested_attributes_for :substeps

子步骤.rb

class Substep < ActiveRecord::Base
  belongs_to :step

表单代码

<%= form_for Step.new, :url => steps_path do |f| %>
  <%= text_field(:step, :title, :value => '', class: 'fly-input input_info', placeholder: 'Process Title', id: 'step_form_title') %>
  <%= text_field(:step, :description, :value => '', class: 'fly-input input_info', placeholder: 'Process Description', id: 'step_form_description') %>
  <%= hidden_field :step, :known %>
  <%= hidden_field_tag :experiment, @experiment.id %>
  <%= f.fields_for :substep do |ff| %>
    <%= render "substep_fields", :f => ff %>
  <% end %>
  <%= link_to_add_association 'Add substep', f, :substeps %>
  <%= f.submit "Done", class: "main_button" %>
<% end %>

_substep_fields.html.erb

<div class='nested-fields'>
  <%= f.text_field :description %>
</div>

steps_controller.rb

def step_params
  params.require(:step).permit(:title, :description, :known, substeps_attributes: [:id, :description, :action, :_destroy])
end

我可以看到第一个输入,并添加第二个、第三个等多个子步骤的输入。问题是,只有第一个子步骤的描述会被传递给控制器​​:

(byebug) params
params
{"utf8"=>"✓", "authenticity_token"=>"xxx", "step"=>{"title"=>"Test Title", "description"=>"Test Desc", "known"=>"-1", "substep"=>{"description"=>"Substep1"}}, "experiment"=>"64", "commit"=>"Done", "controller"=>"steps", "action"=>"create"}

对我的问题有什么想法吗?

编辑 共享添加两个子步骤后生成的 HTML

<form class="new_step" id="new_step" action="/steps" accept-charset="UTF-8" method="post">
<input name="utf8" type="hidden" value="✓"><input type="hidden" name="authenticity_token" value="xxxx">
  <input value="" class="fly-input input_info ui-autocomplete-input" placeholder="Process Title" id="step_form_title" type="text" name="step[title]" data-hasqtip="6" aria-describedby="qtip-6" autocomplete="off">
  <label class="fly-label classic is-active" for="classic">Description</label>
  <input value="" class="fly-input input_info" placeholder="Process Description" id="step_form_description" type="text" name="step[description]" data-hasqtip="7" aria-describedby="qtip-7">
  <input type="hidden" name="step[known]" id="step_known" value="-1">
  <input type="hidden" name="experiment" id="experiment" value="76">
</form>
  <div class="nested-fields">
    <input type="text" name="step[substeps_attributes][1453146839656][description]" id="step_substeps_attributes_1453146839656_description">
  </div>
  <div class="nested-fields">
    <input type="text" name="step[substeps_attributes][1453146844032][description]" id="step_substeps_attributes_1453146844032_description">
  </div>
  <div class="" id="customprocess_processsteps">
    <a class="main_button add_fields" data-association="substep" data-associations="substeps" data-association-insertion-template="<div class='nested-fields'>
  <input type=&quot;text&quot; name=&quot;step[substeps_attributes][new_substeps][description]&quot; id=&quot;step_substeps_attributes_new_substeps_description&quot; />
</div>" href="#">Add substeps</a>
    <button aria-label="Close reveal" class="close-button" data-close="" type="button">
    </button>
  </div>
<input type="submit" name="commit" value="Done" class="main_button">

【问题讨论】:

  • 我猜你解决了@BroiSatse 提到的问题。添加几个子步骤后生成的html可以添加吗?
  • @MichalSzyndel 添加了生成的 HTML
  • 有趣,我认为它应该可以工作

标签: ruby-on-rails ruby-on-rails-4 cocoon-gem


【解决方案1】:

您需要与fields_for 中的关联名称完全匹配。改变这个:

<%= f.fields_for :substep do |ff| %>

<%= f.fields_for :substeps do |ff| %>

编辑:Cocoon 期望严格的 DOM 结构能够正常工作,请尝试更改

<%= f.fields_for :substep do |ff| %>
  <%= render "substep_fields", :f => ff %>
<% end %>
<%= link_to_add_association 'Add substep', f, :substeps %>

收件人:

<div id="substeps">
  <%= f.fields_for :substep do |ff| %>
    <%= render "substep_fields", :f => ff %>
  <% end %>
  <div class="links">
    <%= link_to_add_association 'Add substep', f, :substeps %>
  </div>
</div>

如果我没记错的话,只需要 link_to_add_association 周围的包装器,拥有最顶级的包装器就好了。

【讨论】:

  • 我将其重命名为 :substeps,然后将我的部分重命名为 _substeps_fields.html.erb 以匹配。我现在在“缺少部分实验/_substep_fields”的 link_to_add_association 上遇到错误,
  • 如果不重命名部分,输入最初没有显示,并且添加的第二个/第三个输入仍然没有传入参数。
  • 您不应该重命名部分,最初它是空的事实是正确的(因为没有要显示的关联对象)。你能在改变之后显示你在 params 中得到了什么吗?
  • 啊,我明白了。谢谢。我仍然没有得到我使用添加子步骤按钮添加的两个输入:{"utf8"=>"✓", "authenticity_token"=>"xxxx", "step"=>{"title"=>"新测试标题", "description"=>"新测试描述", "known"=>"-1"}, "experiment"=>"65", "commit"=>"Done", "controller"=> “步骤”,“动作”=>“创建”}
  • 解决问题后是否有效? HTML 看起来应该相应地传递数据。
【解决方案2】:

您需要进行两项更改。一个是 BroiSatse 写的,改变了

<%= f.fields_for :substep do |ff| %>

<%= f.fields_for :substeps do |ff| %>

第二,改变

params.require(:step).permit(..., substeps_attributes: [:id, :description, :action, :_destroy])

params.require(:step).permit(..., substeps_attributes: [[:id, :description, :action, :_destroy]])

【讨论】:

  • 不幸的是得到相同的参数:{"utf8"=>"✓", "authenticity_token"=>"xxx", "step"=>{"title"=>"Test Step Title", "description"=>"Test Step Desc", "known"=>"-1"}, "experiment"=>"82", "commit"=>"Done", "controller"=>"steps", "动作"=>"创建"}
  • 还有我的强参数:step_params {"title"=>"Test Step Title", "description"=>"Test Step Desc", "known"=>"-1"}
  • AFAIK,不需要第二次更改。至少我的应用在没有双括号的情况下运行良好
猜你喜欢
  • 2020-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多