Một số bổ sung nhỏ cho câu trả lời SSR :
accept_nested_attributes_for không yêu cầu bạn thay đổi bộ điều khiển của đối tượng mẹ. Vì vậy, nếu để sửa
name: "post_attachments[avatar][]"
đến
name: "post[post_attachments_attributes][][avatar]"
sau đó tất cả những thay đổi bộ điều khiển như thế này trở nên thừa:
params[:post_attachments]['avatar'].each do |a|
@post_attachment = @post.post_attachments.create!(:avatar => a)
end
Ngoài ra, bạn nên thêm PostAttachment.new
vào biểu mẫu đối tượng mẹ:
Trong 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 %>
Điều này sẽ làm dư thừa thay đổi này trong bộ điều khiển của cha mẹ:
@post_attachment = @post.post_attachments.build
Để biết thêm thông tin, hãy xem Rails fields_cho biểu mẫu không hiển thị, biểu mẫu lồng nhau
Nếu bạn sử dụng Rails 5, thì hãy thay đổi Rails.application.config.active_record.belongs_to_required_by_default
giá trị từ true
thành false
(trong config / initializers / new_framework_defaults.rb) do lỗi bên trong accept_nested_attributes_for (nếu không thì accept_nested_attributes_for thường không hoạt động trong Rails 5).
CHỈNH SỬA 1:
Để thêm về tiêu diệt :
Trong các mô hình / post.rb
class Post < ApplicationRecord
...
accepts_nested_attributes_for :post_attachments, allow_destroy: true
end
Trong 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 %>
Bằng cách này, bạn đơn giản không cần phải có bộ điều khiển của đối tượng con! Ý tôi là không cần bất kỳ thứ PostAttachmentsController
gì nữa. Đối với controller của đối tượng cha ( PostController
), bạn cũng gần như không thay đổi nó - điều duy nhất bạn thay đổi trong đó là danh sách các tham số được liệt kê trong danh sách trắng (bao gồm các tham số liên quan đến đối tượng con) như sau:
def post_params
params.require(:post).permit(:title, :text,
post_attachments_attributes: ["avatar", "@original_filename", "@content_type", "@headers", "_destroy", "id"])
end
Đó là lý do tại sao accepts_nested_attributes_for
rất tuyệt vời.