在 Rails 6 中,我有一个带有文件字段的表单,我正在使用 activestorage 来存储文件。如果在提交表单后验证失败,则重新显示表单并显示验证错误。重新显示表单时如何保留添加到文件字段的文件,以便用户不必再次将文件添加到表单?
rails 5 已经有一个类似的问题:Active Storage: Best practice to retain/cache Uploaded file when form redisplays,但是那里的解决方案仅适用于 Rails 5。
在 Rails 6 中,我有一个带有文件字段的表单,我正在使用 activestorage 来存储文件。如果在提交表单后验证失败,则重新显示表单并显示验证错误。重新显示表单时如何保留添加到文件字段的文件,以便用户不必再次将文件添加到表单?
rails 5 已经有一个类似的问题:Active Storage: Best practice to retain/cache Uploaded file when form redisplays,但是那里的解决方案仅适用于 Rails 5。
由于 Rails 6 不存储分配的文件,我发现的解决方法是在文件字段上启用直接上传。这将在表单提交之前通过 javascript 上传文件。
= f.file_field :doc, direct_upload: true
为此,您还需要将 activestorage.js 添加到您的包中,如Active Storage 指南中所述。
在此更改之后,可以使用问题Active Storage: Best practice to retain/cache Uploaded file when form redisplays中描述的方法。这意味着将 signed_id 添加到您的表单中的隐藏字段中,如下所示:
= f.file_field :doc, direct_upload: true
= f.hidden_field :doc, value: f.object.doc.signed_id if f.object.doc.attached?
除了 Robban 回答,对于多个附件,并做一些预览
= f.file_field :attachments, multiple: true, direct_upload: true
- f.object.attachments.each do |attach|
= f.hidden_field :attachments, value: attach.signed_id, multiple: true
= image_tag attach.preview(resize_to_limit: [100, 100]) if attach.previewable?
= image_tag attach.variant(resize_to_limit: [100, 100]) if attach.variable?
我找到了使用表单发布存储文件的解决方案(无需直接上传)。但它需要额外的代码到通常的脚手架代码@mention = Mention.create(mention_params)
控制器代码:
@mention.screenshot.blob.upload(mention_params[:screenshot])
@mention.screenshot.blob.save
在调试时检查它是否在 active_storage_blob 表中创建了一条记录。
上传文件后,您可以在下次提交时重复使用 signed_id(当模型验证未通过时)。
查看代码:
f.hidden_field :screenshot, value: ...screenshot.signed_id if ...screenshot.attached? %>
这不是一个干净的解决方案,但我想你会明白的。