Ruby on Rails 2.1 - Caricamento di file
Potresti avere un requisito in base al quale desideri che i visitatori del tuo sito caricino un file sul tuo server. Rails rende molto facile gestire questo requisito. Ora procederemo con un semplice e piccolo progetto Rails.
Come al solito, iniziamo con una nuova applicazione Rails chiamata upload. Creiamo una struttura di base dell'applicazione utilizzando il semplice comando rails.
C:\ruby> rails -d mysql upload
Decidiamo dove desideri salvare i file caricati. Supponiamo che lo siadatadirectory all'interno della tua sezione pubblica. Quindi, crea questa directory e controlla le autorizzazioni.
C:\ruby> cd upload
C:\ruby\upload> mkdir upload\public\data
Il nostro prossimo passo sarà come al solito, creare controller e modelli.
Creazione del modello
Poiché non si tratta di un'applicazione basata su database, possiamo mantenere qualsiasi nome ci sia comodo. Supponiamo di dover creare un fileDataFile modello.
C:\ruby\upload> ruby script/generate model DataFile
exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/data_file.rb
create test/unit/data_file_test.rb
create test/fixtures/data_files.yml
create db/migrate
create db/migrate/001_create_data_files.rb
Ora creeremo un metodo chiamato save in data_file.rbfile modello. Questo metodo verrà chiamato dal controller dell'applicazione.
class DataFile < ActiveRecord::Base
def self.save(upload)
name = upload['datafile'].original_filename
directory = "public/data"
# create the file path
path = File.join(directory, name)
# write the file
File.open(path, "wb") { |f| f.write(upload['datafile'].read) }
end
end
La funzione di cui sopra prenderà l'oggetto CGI upload ed estrarrà il nome del file caricato utilizzando la funzione di supporto original_filenamee infine, memorizzerà il file caricato nella directory "public / data". Puoi chiamare la funzione di supportocontent_type per conoscere il tipo di supporto del file caricato.
Qui File è un oggetto rubino e join è una funzione di supporto che concatenerà il nome della directory insieme al nome del file e restituirà il percorso completo del file.
Successivamente, per aprire un file in modalità di scrittura, utilizziamo la funzione di aiuto aperto fornita da Fileoggetto. Inoltre, stiamo leggendo i dati dal file di dati passato e scrivendo nel file di output.
Creazione del controller
Ora creiamo un controller per il nostro progetto di caricamento -
C:\ruby\upload> ruby script/generate controller Upload
exists app/controllers/
exists app/helpers/
create app/views/upload
exists test/functional/
create app/controllers/upload_controller.rb
create test/functional/upload_controller_test.rb
create app/helpers/upload_helper.rb
Ora creeremo due funzioni del controller. La prima funzioneindex chiamerà un file di visualizzazione per ricevere l'input dell'utente e la seconda funzione uploadFileprende le informazioni sui file dall'utente e le passa al modello "DataFile". Abbiamo impostato la directory di caricamento sulla directory "uploads" che abbiamo creato in precedenza "directory = 'data'".
class UploadController < ApplicationController
def index
render :file => 'app\views\upload\uploadfile.html.erb'
end
def uploadFile
post = DataFile.save( params[:upload])
render :text => "File has been uploaded successfully"
end
end
Qui stiamo chiamando la funzione definita nel file del modello. Ilrender viene utilizzata per reindirizzare alla visualizzazione del file e per visualizzare un messaggio.
Creazione della vista
Infine, creeremo un file di visualizzazione uploadfile.rhtml,che abbiamo menzionato nel controller. Popolare questo file con il codice seguente:
<h1>File Upload</h1>
<% form_tag ({:action => 'uploadFile'},
:multipart => true) do %>
<p><label for="upload_file">Select File</label> :
<%= file_field 'upload', 'datafile' %></p>
<%= submit_tag "Upload" %>
<% end %>
Qui tutto è uguale a quello che abbiamo spiegato nei capitoli precedenti. L'unico nuovo tag èfile_field, che creerà un pulsante per selezionare un file dal computer dell'utente.
Impostando il parametro multipart su true, ci si assicura che l'azione passi correttamente lungo i dati binari dal file.
Qui, un punto importante da notare è che abbiamo assegnato "uploadFile" come nome del metodo in :action, che verrà chiamato quando fai clic su Upload pulsante.
Ti mostrerà una schermata come segue:
Ora seleziona un file e caricalo. Questo file verrà caricato nella directory app / public / data con il nome del file effettivo e verrà visualizzato un messaggio che dice che "Il file è stato caricato correttamente".
NOTE - Se un file con lo stesso nome esiste già nella directory di output, verrà sovrascritto.
File caricati da Internet Explorer
Internet Explorer include l'intero percorso di un file nel nome file inviato, quindi il file original_filename la routine restituirà qualcosa come -
C:\Documents and Files\user_name\Pictures\My File.jpg
Invece di solo -
My File.jpg
Questo è facilmente gestibile da File.basename, che rimuove tutto ciò che precede il nome del file.
def sanitize_filename(file_name)
# get only the filename, not the whole path (from IE)
just_filename = File.basename(file_name)
# replace all none alphanumeric, underscore or perioids
# with underscore
just_filename.sub(/[^\w\.\-]/,'_')
end
Eliminazione di un file esistente
Se vuoi eliminare qualsiasi file esistente, è abbastanza semplice. Tutto quello che devi fare è scrivere il seguente codice:
def cleanup
File.delete("#{RAILS_ROOT}/dirname/#{@filename}")
if File.exist?("#{RAILS_ROOT}/dirname/#{@filename}")
end
Per un dettaglio completo su File oggetto, devi passare attraverso il nostro Ruby Reference Manual.