Je dois obtenir le chemin du fichier sur le disque qui utilise ActiveStorage
. Le fichier est stocké localement.
Lorsque j’utilisais Paperclip, j’utilisais la méthode path
de la pièce jointe, qui renvoyait le chemin complet.
Exemple:
user.avatar.path
Tout en regardant Active Storage Docs , cela ressemblait à Rails_blob_path
ferait l'affaire. Après avoir examiné ce qu'il a renvoyé, il ne fournit pas le chemin d'accès au document. Ainsi, il renvoie cette erreur:
Aucun fichier ou répertoire de ce type @ rb_sysopen -
Arrière-plan
J'ai besoin du chemin d'accès au document car j'utilise le gem combine_pdf afin de combiner plusieurs fichiers PDF en un seul fichier PDF.
Pour l'implémentation de Paperclip, j'ai itéré à travers les chemins complets des pièces jointes sélectionnées au format pdf et load
dans le fichier pdf combiné:
attachment_paths.each {|att_path| report << CombinePDF.load(att_path)}
Merci à l'aide de @muistooshort dans les commentaires, après avoir regardé le Code de stockage actif , cela fonctionne:
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
Cette solution me semble un peu difficile. J'aimerais entendre parler d'autres solutions. Cela fonctionne pour moi si.
Il suffit d'utiliser:
ActiveStorage::Blob.service.send(:path_for, user.avatar.key)
Vous pouvez faire quelque chose comme ça sur votre modèle:
class User < ApplicationRecord
has_one_attached :avatar
def avatar_on_disk
ActiveStorage::Blob.service.send(:path_for, avatar.key)
end
end
Je ne sais pas pourquoi toutes les autres réponses utilisent send(:url_for, key)
. J'utilise Rails 5.2.2 et url_for
est une méthode publique, il est donc préférable d'éviter send
ou simplement d'appeler path_for
:
class User < ApplicationRecord
has_one_attached :avatar
def avatar_path
ActiveStorage::Blob.service.path_for(avatar.key)
end
end
Il est à noter que dans la vue, vous pouvez faire des choses comme celle-ci:
<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>
Vous pouvez télécharger la pièce jointe dans un répertoire local, puis la traiter.
En supposant que vous ayez dans votre modèle:
has_one_attached :pdf_attachment
Vous pouvez définir:
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