J'essaie d'afficher le nom de fichier d'une pièce jointe Carrierwave dans un modèle Rails erb. Ce qui suit ne fonctionne pas:
<%= @page.form.filename %>
Cela semble conforme à la documentation . Une étape supplémentaire est-elle nécessaire?
Mon modèle de page ressemble à ceci:
class Page < ActiveRecord::Base
mount_uploader :form, FormUploader
end
L'uploader de formulaire ressemble à ceci:
class FormUploader < CarrierWave::Uploader::Base
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def extension_white_list
%w(pdf)
end
end
La documentation que vous consultez est le fichier nettoyé, c'est ce qu'il utilise pour stocker réellement un fichier. La partie que vous recherchez est FormUploader, qui est un uploader, et fait partie de http://rubydoc.info/gems/carrierwave/0.5.2/CarrierWave/Uploader
Si vous souhaitez obtenir le nom du fichier, vous pouvez soit le lire directement dans la colonne de la base de données, soit utiliser File.basename(@page.form.path)
pour l'extraire facilement.
J'ai pu obtenir le nom de fichier via le paramètre interne file
:
<%= @page.form.file.filename %>
Le Carrierwave docs pourrait être un peu décalé, mais la manière recommandée semble être:
@page.form.file.identifier
La solution de @ adamonduty est excellente. Une autre solution que j'ai utilisée auparavant, il suffit de créer une méthode sur le modèle:
def name
file.path.split("/").last
end
Vous avez raison @epylinkn. La documentation indique l'utilisation:
@page.form.file.identifier
Mais quand j'utilise cela, je reçois toujours nil
(tout comme @Cheng l'a commenté).
J'ai ensuite inspecté mes méthodes d'objets (@page.form.file.methods.inspect
) et a constaté ce qui suit:
@page.form.file_identifier
Dans la classe de téléchargement associée à votre modèle, définissez une méthode de nom de fichier.
def filename
File.basename(path)
end
Vous pouvez ensuite appeler
model_instance.file.filename
Fonctionne à partir de CarrierWave 1.1.0. Il s'agit d'une reformulation/fusion succincte des réponses de kikito et Chris Alley ci-dessus.
Si vous utilisez ActiveRecord, vous pouvez accéder directement au champ nommé form
de deux manières:
def my_method
self[:form]
end
ou
def my_method
form_before_type_cast
end
La deuxième méthode est en lecture seule.
Je suppose que vous avez des modèles comme celui-ci?
class Page
mount_uploader :form, FormUploader
end
Si oui, vous devriez pouvoir appeler:
@page.form.url
@page.form.filename
Êtes-vous sûr d'avoir téléchargé/joint correctement le fichier? Que voyez-vous lorsque vous inspectez @ page.form? N'oubliez pas que la pièce jointe ne sera enregistrée que lorsque vous aurez entièrement traité le téléchargement.
Voici ma solution:
before_save :update_file_attributes
def update_file_attributes
if file.present? && file_changed?
self.content_type = file.file.content_type
self.file_size = file.file.size
self.file_name = read_attribute(:file)
end
end
CarrierWave::SanitizedFile
Possède une méthode privée original_filename
Contenant le nom de fichier du fichier téléchargé. (docs: http://rdoc.info/github/jnicklas/carrierwave/master/CarrierWave/SanitizedFile:original_filename )
Après avoir lu ce fil de la liste de diffusion CarrierWave , aucun ne semblait répondre à mes besoins. Avec quelque chose comme
class Upload < ActiveRecord::Base
mount_uploader :file, FileUploader
# ...
Je modifie fortement la valeur de la colonne :file
À partir du nom de fichier d'origine. Pour cette raison, j'ai décidé de suivre le nom de fichier d'origine dans une colonne distincte de celle liée à CarrierWave. Dans mon FileUploader
j'ai simplement ajouté un lecteur qui encapsule la méthode privée original_filename
:
def original_file
original_filename
end
J'ai ensuite ajouté un événement before_create
À la classe Upload
(mes enregistrements Upload
ne sont jamais modifiés, donc un before_create
est acceptable pour mes besoins)
before_create do
self.original_file = self.file.original_file
end