具有中间模型的 ActiveStorage 多次上传
ActiveStorage multiple upload with intermediate model
目标
我想上传多个文件。因此,一个 Intervention 可以有多个 Uploads,每个 Upload 都有一个附件。这样,每个 Upload 都可以附加一个具有不同状态、名称、可见性等的文件,而不是有一个 Upload has_many_attached
我做了什么
我有一个可以有很多上传的干预模型:
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
在我的 interventions_controller 中:
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
中提取它们,然后在没有任何上传的情况下创建干预,然后为每个保存的上传文件,为新创建的上传创建一个新的上传干预 ?
我已经完成了我提出的建议。我不知道是否有更优雅的方法来做到这一点,但无论如何,这是有效的。
在我的表单中,我刚刚添加了一个简单的 files
字段,可以容纳多个文件
<div class="field">
<%= form.label :files %>
<%= form.file_field :files, multiple: true %>
</div>
我已将此添加到允许的参数中:
params.require(:intervention).permit(:user_id, :comment, files:[]])
然后我通过忽略这个 files
参数来创建我的 Intervention,稍后我用它来创建一个新的 Upload 记录对于每个提交的文件。
# 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
目标
我想上传多个文件。因此,一个 Intervention 可以有多个 Uploads,每个 Upload 都有一个附件。这样,每个 Upload 都可以附加一个具有不同状态、名称、可见性等的文件,而不是有一个 Upload has_many_attached
我做了什么
我有一个可以有很多上传的干预模型:
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
在我的 interventions_controller 中:
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
中提取它们,然后在没有任何上传的情况下创建干预,然后为每个保存的上传文件,为新创建的上传创建一个新的上传干预 ?
我已经完成了我提出的建议。我不知道是否有更优雅的方法来做到这一点,但无论如何,这是有效的。
在我的表单中,我刚刚添加了一个简单的 files
字段,可以容纳多个文件
<div class="field">
<%= form.label :files %>
<%= form.file_field :files, multiple: true %>
</div>
我已将此添加到允许的参数中:
params.require(:intervention).permit(:user_id, :comment, files:[]])
然后我通过忽略这个 files
参数来创建我的 Intervention,稍后我用它来创建一个新的 Upload 记录对于每个提交的文件。
# 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