我有一个Post和一个MaterielLink模型。
帖子has_many materiel_links
和accepts_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的实例,但它们是空的:它们不保存链接/名称。
我哪里出错了?
答案 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