Algumas pequenas adições à resposta SSR :
aceita_nested_attributes_for não requer que você altere o controlador do objeto pai. Então, se corrigir
name: "post_attachments[avatar][]"
para
name: "post[post_attachments_attributes][][avatar]"
então, todas essas mudanças de controlador como essas se tornam redundantes:
params[:post_attachments]['avatar'].each do |a|
@post_attachment = @post.post_attachments.create!(:avatar => a)
end
Além disso, você deve adicionar PostAttachment.new
ao formulário do objeto pai:
Em views / posts / _form.html.erb
<%= f.fields_for :post_attachments, PostAttachment.new do |ff| %>
<div class="field">
<%= ff.label :avatar %><br>
<%= ff.file_field :avatar, :multiple => true, name: "post[post_attachments_attributes][][avatar]" %>
</div>
<% end %>
Isso tornaria redundante essa mudança no controlador dos pais:
@post_attachment = @post.post_attachments.build
Para obter mais informações, consulte Rails fields_for form not show up, anested form
Se você usa Rails 5, mude o Rails.application.config.active_record.belongs_to_required_by_default
valor detrue
para false
(em config / initializers / new_framework_defaults.rb) devido a um bug dentro de accept_nested_attributes_for (caso contrário, accept_nested_attributes_for não funcionará geralmente no Rails 5).
EDIT 1:
Para adicionar sobre destruir :
Em models / post.rb
class Post < ApplicationRecord
...
accepts_nested_attributes_for :post_attachments, allow_destroy: true
end
Em views / posts / _form.html.erb
<% f.object.post_attachments.each do |post_attachment| %>
<% if post_attachment.id %>
<%
post_attachments_delete_params =
{
post:
{
post_attachments_attributes: { id: post_attachment.id, _destroy: true }
}
}
%>
<%= link_to "Delete", post_path(f.object.id, post_attachments_delete_params), method: :patch, data: { confirm: 'Are you sure?' } %>
<br><br>
<% end %>
<% end %>
Dessa forma, você simplesmente não precisa ter um controlador de objeto filho! Quero dizer, nenhum PostAttachmentsController
é mais necessário. Quanto ao controlador do objeto pai ( PostController
), você também quase não o altera - a única coisa que você altera lá é a lista de parâmetros da lista de permissões (para incluir os parâmetros relacionados ao objeto filho) como este:
def post_params
params.require(:post).permit(:title, :text,
post_attachments_attributes: ["avatar", "@original_filename", "@content_type", "@headers", "_destroy", "id"])
end
É por isso que accepts_nested_attributes_for
é tão incrível.