82 votes

Téléchargement d'un fichier dans Rails

Je suis novice en matière de rails, et j'écris un site web RESTful en utilisant la technique CRUD. Jusqu'à présent, j'ai créé trois pages, qui permettent toutes à l'utilisateur de créer, modifier et supprimer une ligne de la base de données. Cependant, ma quatrième page devra inclure un formulaire de téléchargement de fichier, mais a) je ne sais pas comment fonctionne le système de fichiers avec Rails et je ne sais donc pas où les fichiers doivent être stockés. Le fichier serait d'environ 100kb et ne pourrait pas être stocké dans un stockage temporaire parce qu'il sera constamment téléchargé. Et b) je ne sais pas comment écrire dans un fichier.

Ce serait formidable si vous pouviez me dire comment faire ce que j'ai mentionné ci-dessus - créer une entrée de téléchargement sur un formulaire de saisie, et ensuite écrire le fichier dans un chemin de fichier dans un répertoire séparé.

144voto

fabi Points 1079

Mise à jour 2018

Bien que tout ce qui est écrit ci-dessous reste vrai, Rails 5.2 inclut maintenant active_storage qui permet de télécharger directement vers S3 (ou d'autres services de stockage en nuage), de transformer des images, etc. Vous devriez jeter un coup d'œil à la page guide des rails et décidez vous-même de ce qui correspond à vos besoins.


Bien qu'il existe de nombreux outils qui permettent de télécharger des fichiers en toute simplicité (voir https://www.ruby-toolbox.com/categories/rails_file_uploads pour une liste), rails dispose d'aides intégrées qui facilitent la mise en place de votre propre solution.

Utiliser le file_field -dans votre formulaire, et rails s'occupe du téléchargement pour vous :

<%= form_for @person do |f| %>
  <%= f.file_field :picture %>
<% end %>

Vous aurez accès au fichier téléchargé dans le contrôleur de la manière suivante :

uploaded_io = params[:person][:picture]
File.open(Rails.root.join('public', 'uploads', uploaded_io.original_filename), 'wb') do |file|
  file.write(uploaded_io.read)
end

Cela dépend de la complexité de ce que vous voulez réaliser, mais c'est tout à fait suffisant pour des tâches simples de téléchargement de fichiers. Cet exemple est tiré des guides rails, vous pouvez vous y rendre pour plus d'informations : http://guides.rubyonrails.org/form_helpers.html#uploading-files

7voto

Ahmed Elkoussy Points 885

Sept 2018

Pour tous ceux qui ont vérifié cette question récemment, Rails 5.2+ dispose désormais d'ActiveStorage par défaut et je recommande vivement de l'essayer.

Puisqu'il fait partie du noyau Rails 5.2+ maintenant, il est très bien intégré et a d'excellentes capacités dès sa sortie de la boîte (bien que tous les autres gems bien connus comme Carrierwave, Shrine, paperclip,... soient excellents, celui-ci offre de très bonnes fonctionnalités que l'on peut considérer pour tout nouveau projet Rails).

L'équipe de Paperclip a supprimé la gem en faveur de Rails ActiveStorage.

Voici la page github pour ActiveStorage & de nombreuses ressources sont disponibles partout

J'ai également trouvé cette vidéo s'avère très utile pour comprendre les caractéristiques d'Activestorage

3voto

R Milushev Points 2610

Il existe un petit bijou spécialement conçu pour le téléchargement de fichiers : onde porteuse . Si le wiki n'apporte pas d'aide, il existe un belle RailsCast sur la meilleure façon de l'utiliser . En résumé, il existe un champ de type file dans les formulaires Rails, qui invoque la boîte de dialogue de téléchargement de fichier. Vous pouvez l'utiliser, mais la "magie" est faite par carrierwave gemme .

Je ne sais pas ce que vous voulez dire par "comment écrire dans un fichier", mais j'espère que c'est un bon début.

0voto

ray Points 5072

Si vous ne souhaitez pas stocker le fichier dans la base de données mais dans l'application, comme les actifs (dossier personnalisé), vous pouvez définir une variable d'instance non-db définie par attr_accessor : document et l'utiliser. form_for - f.file_field pour obtenir le fichier,

Dans le contrôleur,

 @person = Person.new(person_params)

Ici person_params return whitelisted params[:person] (se définir)

Enregistrer le fichier sous,

dir = "#{Rails.root}/app/assets/custom_path"
FileUtils.mkdir(dir) unless File.directory? dir
document = @person.document.document_file_name # check document uploaded params
File.copy_stream(@font.document, "#{dir}/#{document}")

Note : Ajouter ce chemin dans .gitignore & si vous souhaitez réutiliser ce fichier, ajoutez le chemin suivant asset_path an de la demande par application.rb

Chaque fois qu'un formulaire lit un champ de fichier, il est stocké dans le dossier tmp, vous pouvez ensuite le stocker à votre place, j'ai donné un exemple de stockage à l'actif.

note : Le stockage de fichiers de ce type augmentera la taille de l'application, il est préférable de les stocker dans la base de données à l'aide de paperclip .

0voto

Saif chaudhry Points 368

Dans votre intiallizer/carrierwave.rb

if Rails.env.development? || Rails.env.test?
    config.storage = :file
    config.root = "#{Rails.root}/public"
    if Rails.env.test?
      CarrierWave.configure do |config|
        config.storage = :file
        config.enable_processing = false
      end
    end
 end

l'utiliser pour l'enregistrer dans un fichier lorsqu'il est exécuté en local

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X