Rails ActiveStorage – 不使用模型

huangapple go评论52阅读模式
英文:

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 a 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?

英文:

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

    &lt;%= form_with(
    multipart: true,
    scope: :ctf,
    url:some_path,
    id: dom_id(Import.new, :form),
    data: { turbo: false }
  ) do |form| %&gt;
  &lt;%= render Content::SectionComponent.new do |section| %&gt;
      &lt;span class=&quot;text-sm&quot;&gt;&lt;%= &#39;Upload XML&#39; %&gt;&lt;/span&gt;

        &lt;%= form.label :cf_file, &#39;File&#39; %&gt;

        &lt;%= form.file_field :cf_file, accept: &#39;application/xml&#39;, required: true %&gt;
  &lt;% end %&gt;
&lt;% end %&gt;

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] = &#39;Something went wrong&#39;
      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?

答案1

得分: 1

根据文档ActiveStorage::Blob是一个数据库记录,并且它是根据ActiveRecord模型设计的。

一个可能可行的选择是使用直接上传,这实际上允许你设置一些JavaScript,使文件直接上传到你的存储服务(例如S3),而你的表单提交的是令牌或上传文件的标识符。
但这个解决方案也建立在ActiveStorage::Blob已创建的假设上。所以你可能需要绕过它的方式。

但如果你在问 - 你能创建Blob并将其上传到服务,而不将其附加到任何其他模型吗 - 绝对可以。未附加的Blob是存在的,这就是为什么文档正在解释如何清除它们以便进行清理的原因。

英文:

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.

huangapple
  • 本文由 发表于 2023年5月25日 22:13:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76333261.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定