web-dev-qa-db-fra.com

Télécharger un fichier dans Rails

Je connais Rails depuis peu et j'écris un site Web RESTful en utilisant la technique CRUD. Jusqu'à présent, j'ai créé trois pages, toutes permettant à l'utilisateur de créer, éditer 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 le système de fichiers fonctionne avec Rails, donc je ne sais pas où les fichiers doivent être stockés. Le fichier ferait environ 100 Ko et ne pourrait pas être stocké dans une mémoire temporaire car il serait 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, puis écrire le fichier dans un chemin de fichier dans un répertoire distinct.

64
max_

Mise à jour 2018

Bien que tout ce qui est écrit ci-dessous reste vrai, Rails 5.2 inclut désormais active_storage, qui permet des tâches telles que le téléchargement direct sur S3 (ou d’autres services de stockage dans le cloud), les transformations d’images, etc. Vous devriez consulter le guide Rails et décider pour vous-même ce qui correspond à vos besoins.


Bien qu'il existe de nombreux joyaux qui résolvent joliment le téléchargement de fichiers (voir https://www.Ruby-toolbox.com/categories/Rails_file_uploads } pour une liste), Rails a des aides intégrées qui facilitent les choses rouler votre propre solution.

Utilisez l’assistant file_field- form de votre formulaire et Rails se chargera du téléchargement pour vous:

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

Le contrôleur aura accès au fichier téléchargé comme suit:

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 cela est tout à fait suffisant pour faciliter le téléchargement de fichiers. Cet exemple est tiré des guides Rails, vous pouvez y accéder pour plus d'informations: http://guides.rubyonrails.org/form_helpers.html#uploading-files

112
fabi

Il existe un joyau de Nice spécialement pour le téléchargement de fichiers: carrierwave . Si le wiki ne vous aide pas, il existe un Nice RailsCast sur la meilleure façon de l'utiliser. Pour résumer, il existe un type de champ file dans les formulaires Rails, qui appelle la boîte de dialogue de téléchargement de fichier. Vous pouvez l'utiliser, mais la "magie" est faite par carrierwave gem. 

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

3
R Milushev

Sept 2018

Pour ceux qui vérifient cette question récemment, Rails 5.2+ a maintenant ActiveStorage par défaut et je recommande vivement de la vérifier.

Comme il fait maintenant partie intégrante du noyau de Rails 5.2+, il est très bien intégré et présente d’excellentes capacités hors de la boîte (tous les autres joyaux connus tels que Carrierwave, Shrine, Paperclip, ... sont excellents, mais celui-ci est très utile. bonnes fonctionnalités que nous pouvons considérer pour tout nouveau projet Rails)

L'équipe de trombones a déconseillé la gemme au profit de Rails ActiveStorage.

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

J'ai aussi trouvé cette vidéo très utile pour comprendre les fonctionnalités d'Activestorage

1
Ahmed Elkoussy

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

Dans le contrôleur,

 @person = Person.new(person_params)

Ici, person_params renvoie la liste blanche params[:person] (définissez vous-même)

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}")

Remarque: Ajoutez ce chemin dans .gitignore et si vous souhaitez utiliser ce fichier à nouveau, ajoutez ce chemin asset_pathan d’application par application.rb.

Chaque fois que le champ de fichier lu est enregistré, il est stocké dans le dossier tmp. Vous pouvez ensuite le stocker chez vous.

note : Le stockage de fichiers comme celui-ci augmentera la taille de l'application, il est préférable de le stocker dans la base de données à l'aide de Paperclip.

0
ray

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

utilisez-le pour stocker dans un fichier lors de l'exécution sur local

0
Saif chaudhry