嵌套表单创建空实例

Nested forms creates empty instances

我有一个 Post 和一个 MaterielLink 模型。 一个posthas_many materiel_linksaccepts_nested_attributes_for :materiel_links

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

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

在我的 post 控制器中:

 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 应用程序的特定原因,post 是在呈现 posts/new 页面时创建的(它创建为空,并且用户只是更新它而不是实际创建它)。所以 post 已经存在,但不存在我必须在更新操作中创建的 materiel_links。

和参数:

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

我在更新操作中添加了一个 raise,奇怪的是,当我输入 [=19] 时,我可以为我添加的每个 materiel_link 找到 link/name =] 但每对夫妇前都有一个数字:

>> 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 的实例已创建,但它们是空的:它们不保存 link/name。

我哪里错了?

我的猜测是因为在你的更新操作中你在 .update 之前使用了 .build,它以某种方式与 .update 冲突,因为 materiel_links 值再次传递到那里.您不再需要构建 update 操作;但仅在 edit 操作中,因为 materiel_links 将在调用 .update(post_params) 时自动成为 created/updated,因为 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就可以更新了(如果只是创建就不需要加入白名单,不需要更新)。您可能还想允许销毁。更新如下:

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