因此,我有一个items/new.html.erb
页面,该页面具有用于新Items
记录的表单。
现在,页面在新记录表单旁边还有一个图像上传部分,用户可以在其中上传多张图像。这种UI设计建议用户应该能够上传图像,或将图像附加到要创建的记录上。
我当前的设置是,当用户在页面中上传图片时(通过AJAX / rails UJS处理),id
的上传图片会被添加到新{ {1}}形式。然后,只有在提交主表单后,图像才会被附加到新创建的Item
资源上。我觉得这是处理此问题的一种不寻常的方式,并且有一种更简单,清晰的Rails方式。
我这样称呼图像:
Item
该页面还允许用户排序或更新图像附件的顺序,但是我认为这是一个主题,应该在另一个讨论中。
在Rails中,如何正确,清晰地处理第一个问题?
答案 0 :(得分:1)
Rails具有一个称为accepts_nested_attributes
的内置机制。这样您就可以在同一请求中创建嵌套记录:
class Item
has_many :images
accepts_nested_attributes_for :images
end
class Image
belongs_to :item
has_one_attached :file
end
这将使您可以创建具有以下内容的项目和图像:
Item.create(name: 'Foo', image_attributes: [{ file: 'foo.jpg'}, { file: 'bar.jpg'}])
ActiveRecord将按正确的顺序处理记录。
这使您拥有一个不可为空的外键(item_id
)并避免了孤立的记录,这是解决方案中一个非常实际的问题。 Referential integrity在优先级列表中应该很高。
这与视图中的fields_for
(在表单中)一起在模型中使用。
<%= form_with(model: @item) do |form| %>
<%= form.fields_for(:images) do |image_fields| %>
<%= image_fields.file_field :file %>
<% end %>
<% end %>
并通过在强参数中传递键数组:
params.require(:item).permit(:name, image_attributes: [:file])
has_many_attached
ActiveStorage还使您可以使用has_many_attached
在没有模型的情况下设置一对多关联。附件存储在active_storage_attachments
表中。但是据我所知,没有办法将附加元数据(例如订购)附加到附件。