2012-06-06 44 views
12

Sto cercando una soluzione che permetta all'utente di caricare più immagini attraverso un file_field. Ho cercato opzioni come Jquery File Upload e Uploadify ma non ho ancora trovato buoni esempi con una soluzione funzionante.Rails Paperclip e caricamenti di più file

ho già più di setup immagini,

has_attached_file :asset, 
        :styles => { :large => "640x480", :medium => "300x300", :thumb => "100x100" }, 
        :storage => :s3, 
        :s3_credentials => "#{Rails.root}/config/s3.yml", 
        :path => "/:contributor_id/:listing_name/:filename" 

In questo momento sto Visualizzazione 5 singoli file_fields

def new 
    @listing = Listing.new 
    5.times {@listing.assets.build } 

    respond_to do |format| 
    format.html # new.html.erb 
    format.json { render json: @listing } 
    end 
end 

vorrei avere

<%= f.file_field :asset, :multiple => true %> 

che permette all'utente di seleziona più file nel loro browser di file. Ma come posso elaborarli con un modello annidato? E falli caricare.

risposta

34

Quindi ci sono alcuni problemi qui.

In primo luogo, il metodo has_attached_file di Paperclip non è un'associazione a molti file. Sembra che tu stia cercando di costruire una "risorsa" come se fosse un'associazione Rails. Tutto Paperclip fa mettere un paio di campi nella tua tabella per memorizzare alcuni metadati sul file e ottieni un file allegato per la dichiarazione di has_attached_file. Se si desidera allegare 5 file, si avrebbe bisogno di fare qualcosa di simile:

has_attached_file :asset1 
has_attached_file :asset2 
has_attached_file :asset3 
has_attached_file :asset4 
has_attached_file :asset5 

O, in alternativa, si potrebbe creare un altro modello solo per memorizzare i file. Per esempio:

class Listing < ActiveRecord::Base 
    has_many :assets 
end 

class Asset < ActiveRecord::Base 
    belongs_to :listing 
    has_attached_file :picture 
end 

In questo modo, si potrebbe avere più risorse collegate a un elenco (non ha detto quello che l'oggetto originale è stato così ho ha definito "messa in vendita").

In secondo luogo, non v'è alcuna cosa come un caricamento di più file in HTML (e, come tale, il metodo file_field non prende un argomento :multiple => true. Dovrete usare qualcosa al di là di Rails incorporati in forma l'uso, se vuoi caricare più file. Uploadify è una scelta decente (che ho usato prima). C'è una gemma che trasformerà i campi dei file per utilizzare uploadify (e supporterà la sintassi :multiple => true che desideri): https://github.com/mateomurphy/uploadify_rails3/wiki.

Il mio consiglio sarebbe di iniziare passo dopo passo. Caricare tramite Flash su Rails può essere un processo complicato che implica la gestione del meta-tag CSRF e di altri campi nel modulo. Inizia facendo un modulo che permetta a un utente di carica un file e lo memorizza tramite Paperclip. Quindi, in caso contrario, è possibile suddividere la dichiarazione has_attached_file in un altro modello in modo da poter avere uno o più file associati a un modello (come mostrato nel blocco di codice multi-modello sopra). Quindi prova ad aggiungere Uploadify o un'altra alternativa. Ernie Miller ha un tutorial decente sull'integrazione di Uploadify: http://erniemiller.org/2010/07/09/uploadify-and-rails-3/.

Per iniziare, ricordare che has_attached_file è possibile allegare solo un file. Quando provi a chiamare @listing.assets non ci sono "risorse". C'è un asset. Devi creare un modello separato e utilizzare le associazioni di Rails se vuoi più file.

+0

Ho già creato un altro modello chiamato "Elenco". Una lista ha molti beni. Posso già caricare più risorse, ma non attraverso un singolo campo "Scegli file". se qualcuno ha dei buoni esempi usando uploadify sarebbe fantastico. Non sono sicuro di come eseguire lo sfondo JS per elaborare ogni immagine e POST sul server in modo corretto. – kcollignon

+3

Puoi aggiungere ': multiple =>" multiple "' al tuo 'file_field', che abilita la selezione di più file da un campo di input di file html (almeno in Chrome). Non ho ancora risolto il problema di gestire correttamente questi caricamenti, ma so che il parametro post include una serie di file multipli che hai selezionato e caricato. –

+0

E devi anche aggiungere ': html => {: multipart =>: true}' al tuo 'form_for'. –

2

La risposta accettata dice che non esiste un caricamento di più file in HTML.

<%= f.file_field :files, multiple: true %> 

Ciò consente di selezionare più immagini e inviarle come matrice.

Se avete il rapporto Dog has_many Images e Image has_attachment :file, fare questo per ottenere più immagini da caricare in una sola volta:

Nella tua html.erb

<%= form_for @dog, html: { multipart: true } do |f| %> 
    <%= f.file_field :files, accept: 'image/png,image/jpeg,image/gif', multiple: true %> 
<%= end %> 

Nel vostro controller

def dog_params 
    params.require(:dog).permit files: [] 
end 

Nel tuo cane modello

def files=(array = []) 
    array.each do |f| 
    images.create file: f 
    end 
end 

Si presume che tu sia già in grado di caricare un'immagine ma di eseguire l'aggiornamento a più immagini contemporaneamente. Si noti che il tempo di attesa aumenterà.

Per ridurre il tempo di attesa, sbirciare il mio post su questa domanda relativa al caricamento veloce.

Problemi correlati