I want to upload multiple files. So one Intervention can have multiple Uploads and each Upload has one attached file to it. This way, each Upload can have one file attached with different status, name, visibility, etc. instead of having one Upload with has_many_attached
I have one Intervention model that can have many uploads :
class Intervention < ApplicationRecord
has_many :uploads, dependent: :destroy
accepts_nested_attributes_for :uploads, :allow_destroy => true
end
Each uploads has one attached file using ActiveStorage :
class Upload < ApplicationRecord
belongs_to :intervention
has_one_attached :file
end
In my interventions_controller I do :
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
In my form I have :
<%= 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 %>
This solution works when I want to upload only one file. But if I want to upload two files I can't figure out. I can add multiple: true
to the file_field
but how to created multiple Upload with one file each ?
Should I save the uploaded files into a temp variable first, extract them from the intervention_params
, then create the Intervention without any Upload, then for each uploaded files saved, build a new Upload for the newly created Intervention ?
I have done what I have proposed. I don't know if there is a more elegant way to do it but anyway, this is working.
In my form I just added a simple files
field that can take multiple files
<div class="field">
<%= form.label :files %>
<%= form.file_field :files, multiple: true %>
</div>
I have added this to the permitted parameters :
params.require(:intervention).permit(:user_id, :comment, files:[]])
Then I create my Intervention by ignoring this files
params and I use it later to create a new Upload record for each files submitted.
# 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