嵌套表单创建空实例
Nested forms creates empty instances
我有一个 Post 和一个 MaterielLink 模型。
一个posthas_many materiel_links
和accepts_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
我有一个 Post 和一个 MaterielLink 模型。
一个posthas_many materiel_links
和accepts_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
:
>> 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