web-dev-qa-db-ja.com

ディスク上のActiveStorageファイルへのパスを取得します

ActiveStorageを使用しているディスク上のファイルへのパスを取得する必要があります。ファイルはローカルに保存されます。

Paperclipを使用していたとき、フルパスを返す添付ファイルでpathメソッドを使用しました。

例:

user.avatar.path

Active Storage Docs を見ていると、Rails_blob_pathトリックを行います。ただし、返されたものを確認した後、ドキュメントへのパスは提供されません。したがって、次のエラーを返します。

そのようなファイルまたはディレクトリはありません@ rb_sysopen-

背景

combine_pdf gemを使用して複数のpdfを1つのpdfに結合するため、ドキュメントへのパスが必要です。

Paperclip実装では、選択したpdf添付ファイルのfull_pathsを繰り返し処理し、loadを組み合わせてpdfにしました。

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

コメントの@muistooshortのおかげで、 Active Storage Code を見た後、これは機能します:

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

このソリューションは、私にとって少しハック感があります。私は他の解決策を聞きたいです。これは私にとってはうまくいきます。

9
Neil

ただ使用する:

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
20
vitormil

他のすべての回答が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>
7
ecoologic

添付ファイルをローカルディレクトリにダウンロードして処理できます。

モデルに次のものがあるとします:

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
3
ldl