Search code examples
ruby-on-railsfilerails-activestorage

Rails ActiveStorage - without model


I have a Feature where user uploads an XML file and the system should read the file and import data. So the file is not attached to any Model Record. So I have a form which allows file input

    <%= form_with(
    multipart: true,
    scope: :ctf,
    url:some_path,
    id: dom_id(Import.new, :form),
    data: { turbo: false }
  ) do |form| %>
  <%= render Content::SectionComponent.new do |section| %>
      <span class="text-sm"><%= 'Upload XML' %></span>

        <%= form.label :cf_file, 'File' %>

        <%= form.file_field :cf_file, accept: 'application/xml', required: true %>
  <% end %>
<% end %>

In the controller, I get the file as param and manually upload it using ActiveStorage::Blob.

    def cf_upload
      importer = Import.new(cf_upload_params)
      if importer.valid?
        file_storage = ActiveStorage::Blob.create_and_upload!(io: cf_upload_params[:cf_file], filename: filename)
        Importers::Cf::ImportJob.perform_later(file_storage)
      else
        flash.now[:alert] = 'Something went wrong'
      end
      render :index
    end

Is there any way I can use ActiveStorage direct_upload for this instead of doing upload using ActiveStorage::Blob.create_and_upload?


Solution

  • According to the docs ActiveStorage::Blob is a database record, and it has been designed with ActiveRecord models in mind.

    One possibly viable option for you would be to use Direct Uploads which essentially allows you to set up some JS so the file is uploaded directly to your storage service (e.g. S3) and what your form submits is a token, or the identifier of the uploaded file. But this solution is also built on the assumption the ActiveStorage::Blob is created. So probably you'd need to hack your way around it.

    But if you're asking - can you create the blob and upload it to the service without attaching it to any other model - absolutely. Unatached blobs are a thing, which is why the docs are explaining how to purge them if you want to clean up house.