2009-11-04 10 views
29

Come si gestisce il caricamento di file in binario senza collegarli alla registrazione attiva?
Voglio solo scrivere i file sul disco.caricamento di file senza activerecord

Grazie,

+0

Prova questa http://easyrails.herokuapp.com/blogs/5/upload-file-in-rails-without-model- creazione – vajapravin

risposta

54

Se ho capito bene quello che vi serve allora l'esempio più semplice sarebbe questo:

Il controllore:

class UploadController < ApplicationController 
    def new 

    end 

    def create 
    name = params[:upload][:file].original_filename 
    path = File.join("public", "images", "upload", name) 
    File.open(path, "wb") { |f| f.write(params[:upload][:file].read) } 
    flash[:notice] = "File uploaded" 
    redirect_to "/upload/new" 
    end 
end 

La vista:

<% flash.each do |key, msg| %> 
    <%= content_tag :div, msg, :class => [key, " message"], :id => "notice_#{key}" %> 
<% end %> 
<% form_tag '/upload/create', { :multipart => true } do %> 
    <p> 
    <%= file_field_tag 'upload[file]' %> 
    </p> 
    <p> 
     <%= submit_tag "Upload" %> 
    </p> 
<% end %> 

Ciò permetterà di caricare qualsiasi file senza alcun controllo o convalida che a mio parere non è così utile.

Se lo facessi da solo, userei qualcosa come validatable gem o tableless gem solo che tableless non è più supportato. Queste gemme ti permetteranno di convalidare ciò che stai caricando per renderlo più sano.

+1

Assicurati di usare <% = form_tag ...%> nelle guide 3. – cider

+0

per essere coerenti non dovresti usare 'File.join (" pubblico "," immagini "," caricamento ")' per creare la directory ' '? – Crashalot

+0

Certo, è un buon consiglio. Ho scritto molto tempo fa :) Non credo di saperlo fare al momento :) Ho appena usato degli esempi per la codifica, quindi in una riga lo uso :)) Dall'altra non lo faccio. Aggiornamento ora. –

0

Si potrebbe provare a utilizzare i plug-in Rails Attachment_fu per gestire upload di file. Ti consente di salvare i caricamenti sul file system anziché sul database.

+0

attachement_fu bisogno di activerecord .... – Mike

3

La documentazione Tempfile mostra un esempio che è equivalente al codice di Rytis, che va bene la maggior parte del tempo. Ma quando chiami tempfile.read, Ruby legge l'intero file come un singolo blocco in memoria, che è sub-ottimale.

Tuttavia, FileUtils fornisce un metodo copy_stream e IO, almeno in Ruby 2.0, fornisce un copy_stream attuazione che gestisce scrivendo direttamente un percorsofile (FileUtils.copy_stream richiede oggetti simili a file su entrambi i lati, o così dicono i documenti).

Nel mio caso, stavo iniziando un grande caricamento multi-file tramite AJAX, e volevo evitare di leggere l'intero file (s) nella memoria di Ruby prima di scrivere su disco.

Nell'esempio riportato di seguito, è un params[:files]Array di ActionDispatch::Http::UploadedFile casi, e local_filepath è una stringa che punta a un file inesistente in una directory esistente. Per brevità, io supporre che sto solo caricando un file:

IO.copy_stream(params[:files][0].tempfile, local_filepath) 

L'istanza ActionDispatch::Http::UploadedFile ha un campo .tempfile che è solo un normale Tempfile istanza.

In realtà non sono sicuro che Ruby stia ancora leggendo l'intero file in memoria, non ho eseguito il benchmark, ma è molto più possibile di quanto non sia con la sintassi localfile.write(tempfile.read).

tl; dr: IO.copy_stream(your_tempfile, your_disk_filepath) è più conciso, se non più veloce.

4

si può semplicemente spostare il file temporaneo al percorso destino usando fileutils

tmp = params[:my_file_field].tempfile 
destiny_file = File.join('public', 'uploads', params[:my_file_field].original_filename) 
FileUtils.move tmp.path, destiny_file 
Problemi correlati