Can Rails Active Storage be used without a model backing it? I have a form where I need a file to be uploaded but I don't wish it to be attached to a model. I just need the file uploaded so I can process it with a background job and then delete it.
Yes.
When ActiveStorage is backed by a model, there are two parts involved:
ActiveStorage::Blob
record that holds the file info in the active_storage_blobs
tableActiveStorage::Attachment
record that connects the blob to the model using the active_storage_attachments
tableYou can skip creating the ActiveStorage::Attachment
record if you call create_and_upload!
directly. This will create a unique key, determine the content type, compute a checksum, store an entry in active_storage_blobs
, and upload the file:
filename = 'local_file.txt'
file = File.open(filename)
blob = ActiveStorage::Blob.create_and_upload!(io: file, filename: filename)
You can download later with:
blob.download
And delete with:
blob.purge
If you want to skip the storage of the ActiveStorage::Blob
entirely, you would need to go directly to the storage service that manages uploading and downloading files. For example, if you are using Disk
storage you'd see something like this:
ActiveStorage::Blob.service
=> #<ActiveStorage::Service::DiskService ...
Then you'd have to generate your own key and do something like:
service = ActiveStorage::Blob.service
key = 'some_unique_key'
service.upload(key, file)
service.download(key)
service.delete(key)
To upload a file without a model you can use form_with
and specify a url
like:
<%= form_with url: "/uploads", multipart: true do |form| %>
<%= form.file_field :picture %>
<%= form.submit %>
<% end %>
Then on the server you can get the file
with:
file = params[:picture]
blob = ActiveStorage::Blob.create_and_upload!(io: file, filename: file.original_filename)
...