嵌套表单创建空实例

时间:2016-03-31 13:57:40

标签: ruby-on-rails forms nested-forms cocoon-gem

我有一个Post和一个MaterielLink模型。 帖子has_many materiel_linksaccepts_nested_attributes_for :materiel_links

我使用gem cocoon创建嵌套表单:在帖子表单上,我希望能够添加将在提交表单时创建的链接。

post / new.html.erb:

<%= simple_form_for @post, :html => { :id => "post_form", "data-post-id" => @post.id } do |f| %>
  <%= f.simple_fields_for :materiel_links do |materiel_link| %>
    <%= render 'materiel_link_fields', f: materiel_link %>
  <% end %>

  <%= link_to_add_association 'Ajouter', f, :materiel_links%> 
<% end %>

_materiel_link_fields.html.erb:

<%= f.fields_for :materiel_links do |materiel_link| %>
  <%= materiel_link.text_field :name %>
  <%= materiel_link.text_field :link %>
<% end %>

在我的帖子控制器中:

 def update
    @materiel_links = @post.materiel_links.build(post_params[:materiel_links_attributes]

    if @post.update!(post_params)
      session[:current_draft_post_id] = nil
      redirect_to post_path(@post)
    else
      render :new
    end
  end

我在更新操作中,因为我的rails应用特定的原因,帖子是在呈现帖子/新页面时创建的(它被创建为空,用户只是更新它而不是实际创建它) 。所以帖子已经存在,但不是我必须在更新操作中创建的materiel_links。

并且参数:

def post_params
    params.require(:post).permit(:title, materiel_links_attributes: [:name,:link] )
end

我在更新操作中添加了raise,而且我可以找到每个materiel_link的链接/名称,当我输入params但是有一个数字时我已经添加了这个链接/名称在每对夫妻面前:

>> params
{"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"wqzWfaAcwrOOdxViYBO5HaV2bwsNsf5HsvDFEbBYapkOMAPXOJR7oT4zQHbc/hTW8T9a+iH5NRl1WUApxrIjkA==", "post"=>{"title"=>"my title", "materiel_links_attributes"=>{"1459431927732"=>{"materiel_links"=>{"name"=>"mon Lien 1", "link"=>"htttp1"}}, "1459431933881"=>{"materiel_links"=>{"name"=>" Mon lien 2", "link"=>"htttp2"}}}}, "controller"=>"posts", "action"=>"update", "id"=>"1250"}

但是当我输入post_params时,materiel_links哈希中没有任何内容:

>> post_params
=> {"title"=>"my title","materiel_links_attributes"=>{"1459431927732"=>{}, "1459431933881"=>{}}}

创建了MaterielLink的实例,但它们是空的:它们不保存链接/名称。

我哪里出错了?

1 个答案:

答案 0 :(得分:1)

我的猜测是因为在您的更新操作中,您在.build之前使用了.update,它在某种程度上与.update冲突,因为materiel_links值再次传递到那里。您不再需要构建update动作;但仅限于edit操作,因为在调用.update(post_params)时将自动创建/更新materiel_links,因为post_params已包含materiel_links值。尝试

def update
  if @post.update!(post_params)
    @materiel_links = @post.materiel_links

    session[:current_draft_post_id] = nil
    redirect_to post_path(@post)
  else
    render :new
  end
end

您还需要在强参数中将materiel_link的ID列入白名单,以便可以更新表单中的这些materiel_links(如果只是创建,则不需要将ID列入白名单,也不需要更新)。您可能还想允许销毁。更新到以下内容:

def post_params
  params.require(:post).permit(:title, materiel_links_attributes: [:id, :name, :link, :_destroy] )
end

# post.rb
accepts_nested_attributes_for :materiel_links, allow_destroy: true