web-dev-qa-db-fra.com

Affichage d'un nom de fichier Carrierwave dans la vue

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
50
Chris Alley

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.

80
Zachary Anker

J'ai pu obtenir le nom de fichier via le paramètre interne file:

<%= @page.form.file.filename %>
79
kikito

Le Carrierwave docs pourrait être un peu décalé, mais la manière recommandée semble être:

@page.form.file.identifier
14
epylinkn

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
9
omarvelous

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
6
skplunkerin

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.

4

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.

4
adamlamar

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.

2
Winfield

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
1
why

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
1
deefour