Get path to ActiveStorage file on disk
I'm not sure why all the other answers use send(:url_for, key)
. I'm using Rails 5.2.2 and path_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>
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
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.
Use:
ActiveStorage::Blob.service.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.path_for(avatar.key)
end
end