Get path to ActiveStorage file on disk

拈花ヽ惹草 提交于 2019-11-29 11:03:00

问题


I need to get the path to the file on disk which is using ActiveStorage. The file is stored locally.

When I was using paperclip, I used the path method on the attachment which returned the full path.

Example:

user.avatar.path

While looking at the Active Storage Docs, it looked like rails_blob_path would do the trick. After looking at what it returned though, it does not provide the path to the document. Thus, it returns this error:

No such file or directory @ rb_sysopen -

Background

I need the path to the document because I am using the combine_pdf gem in order to combine multiple pdfs into a single pdf.

For the paperclip implementation, I iterated through the full_paths of the selected pdf attachments and load them into the combined pdf:

attachment_paths.each {|att_path| report << CombinePDF.load(att_path)}

回答1:


Just use:

ActiveStorage::Blob.service.send(:path_for, user.avatar.key)

You can do something like this on your model:

class User < ApplicationRecord
  has_one_attached :avatar

  def avatar_on_disk
    ActiveStorage::Blob.service.send(:path_for, avatar.key)
  end
end



回答2:


I'm not sure why all the other answers use send(:url_for, key). I'm using Rails 5.2.2 and url_for is a public method, therefore, it's way better to avoid send, or simply call path_for:

class User < ApplicationRecord
  has_one_attached :avatar

  def avatar_path
    ActiveStorage::Blob.service.path_for(avatar.key)
  end
end

Worth noting that in the view you can do things like this:

<p>
  <%= image_tag url_for(@user.avatar) %>
  <br>
  <%= link_to 'View', polymorphic_url(@user.avatar) %>
  <br>
  Stored at <%= @user.image_path %>
  <br>
  <%= link_to 'Download', rails_blob_path(@user.avatar, disposition: :attachment) %>
  <br>
  <%= f.file_field :avatar %>
</p>



回答3:


Thanks to the help of @muistooshort in the comments, after looking at the Active Storage Code, this works:

active_storage_disk_service = ActiveStorage::Service::DiskService.new(root: Rails.root.to_s + '/storage/')
active_storage_disk_service.send(:path_for, user.avatar.blob.key)
  # => returns full path to the document stored locally on disk

This solution feels a bit hacky to me. I'd love to hear of other solutions. This does work for me though.




回答4:


You can download the attachment to a local dir and then process it.

Supposing you have in your model:

has_one_attached :pdf_attachment

You can define:

def process_attachment      
   # Download the attached file in temp dir
   pdf_attachment_path = "#{Dir.tmpdir}/#{pdf_attachment.filename}"
   File.open(pdf_attachment_path, 'wb') do |file|
       file.write(pdf_attachment.download)
   end   

   # process the downloaded file
   # ...
end


来源:https://stackoverflow.com/questions/50340043/get-path-to-activestorage-file-on-disk

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!