Получить путь к файлу ActiveStorage на диске
Мне нужно получить путь к файлу на диске, который использует ActiveStorage
. Файл хранится локально.
Когда я использовал скрепку, я использовал метод path
во вложении, который возвращал полный путь.
Пример:
user.avatar.path
Если посмотреть на документы Active Storage, похоже, что rails_blob_path
. После просмотра того, что он возвратил, он не указывает путь к документу. Таким образом, он возвращает эту ошибку:
Нет такого файла или каталога @rb_sysopen -
Фон
Мне нужен путь к документу, потому что я использую гем comb_pdf для объединения нескольких PDF файлов в один PDF файл.
Для реализации скрепки я перебрал полные пути выбранных вложений PDF и load
их в объединенный файл PDF:
attachment_paths.each {|att_path| report << CombinePDF.load(att_path)}
Ответы
Ответ 1
Благодаря помощи @muistooshort в комментариях, после просмотра кода Active Storage, это работает:
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
Это решение кажется мне немного странным. Я хотел бы услышать о других решениях. Это работает для меня, хотя.
Ответ 2
Просто используйте:
ActiveStorage::Blob.service.send(:path_for, user.avatar.key)
Вы можете сделать что-то подобное на вашей модели:
class User < ApplicationRecord
has_one_attached :avatar
def avatar_on_disk
ActiveStorage::Blob.service.send(:path_for, avatar.key)
end
end
Ответ 3
Я не уверен, почему все другие ответы используют send(:url_for, key)
. Я использую Rails 5.2.2, а url_for
является публичным методом, поэтому лучше избегать send
или просто вызывать path_for
:
class User < ApplicationRecord
has_one_attached :avatar
def avatar_path
ActiveStorage::Blob.service.path_for(avatar.key)
end
end
Стоит отметить, что в представлении вы можете делать такие вещи:
<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>
Ответ 4
Вы можете загрузить приложение в локальный каталог, а затем обработать его.
Предположим, что у вас есть в вашей модели:
has_one_attached :pdf_attachment
Вы можете определить:
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