带有中间模型的 ActiveStorage 多次上传

Posted

技术标签:

【中文标题】带有中间模型的 ActiveStorage 多次上传【英文标题】:ActiveStorage multiple upload with intermediate model 【发布时间】:2021-10-17 17:41:45 【问题描述】:

目标

我想上传多个文件。因此,一个干预可以有多个上传,每个上传都有一个附加文件。这样,每个 Upload 可以附加一个具有不同状态、名称、可见性等的文件,而不是一个带有 has_many_attached

Upload

我做了什么

我有一个可以有很多上传的干预模型:

class Intervention < ApplicationRecord
  has_many :uploads, dependent: :destroy
  accepts_nested_attributes_for :uploads, :allow_destroy => true
end

每次上传都有一个使用 ActiveStorage 的附件:

class Upload < ApplicationRecord
  belongs_to :intervention
  has_one_attached :file
end

在我的干预控制器中我这样做:

def new
  @intervention = Intervention.new
  @intervention.uploads.build
end

def create
  @intervention = Intervention.new(intervention_params)
  # + default scaffolded controller [...]
end

def intervention_params
  params.require(:intervention).permit(:user_id, :comment, uploads_attributes: [:status, :file])
end

在我的表格中,我有:

<%= form.fields_for :uploads, Upload.new do |uploads_attributes|%>
    <%= uploads_attributes.label :file, "File:" %>
    <%= uploads_attributes.file_field :file %>

    <%= uploads_attributes.hidden_field :status, value: "raw" %>
<% end %>

问题

当我只想上传一个文件时,此解决方案有效。但是,如果我想上传两个文件,我无法弄清楚。我可以将multiple: true 添加到file_field 但如何创建多个上传,每个上传一个文件?

我是否应该先将上传的文件保存到一个临时变量中,从intervention_params 中提取它们,然后在没有任何上传的情况下创建干预,然后为每个保存的上传文件,为新创建的干预构建一个新的上传?

【问题讨论】:

【参考方案1】:

我已经按照我的建议做了。我不知道是否有更优雅的方法可以做到这一点,但无论如何,这是可行的。

在我的表单中,我刚刚添加了一个简单的files 字段,可以接收多个文件

<div class="field">
  <%= form.label :files %>
  <%= form.file_field :files, multiple: true %>
</div>

我已将此添加到允许的参数中: params.require(:intervention).permit(:user_id, :comment, files:[]])

然后我通过忽略这个files 参数来创建我的干预,然后我使用它为每个提交的文件创建一个新的上传记录。

# First create the intervention without the files attached
@intervention = Intervention.new(intervention_params.except(:files))

if @intervention.save
  # Then for each files attached, create a separate Upload
  intervention_params[:files].each do |f|
    upload = @intervention.uploads.new()
    upload.file.attach(f)
    upload.save
  end
end

【讨论】:

以上是关于带有中间模型的 ActiveStorage 多次上传的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Rails 中正确使用 ActiveStorage 进行模型测试?

使用 ActiveStorage 将 Cloudinary 图像附加到 Rails 模型

无法使用带有ActiveStorage image_processing gem的变体显示图像

Rails ActiveStorage 错误 - MessageVerifier-InvalidSignature

从 ActiveStorage 迁移到 Shrine 的 Rake 任务

AnyLogic 多次运行带有随机变量的模型