2012-04-27 16 views
6

Desidero creare una registrazione utente in 3 step con caricamento di avatar al 2 ° passaggio. Quindi seguo la guida di Ryan Bates http://railscasts.com/episodes/217-multistep-forms. Sto usando la gemma CarrierWave per gestire i caricamenti. Ma sembra che non riesco a memorizzare le informazioni del file caricato nella sessione utente (sto ottenendo non può scaricare errore del file). Io uso seguente tecnica controllerModulo multi step con uploader di immagini

Aiuta realtà. Ma quando ho caricare crash proibito tipo di file di tutto su questa linea

@uploader.store!(params[:user][:img_path]) 

con questo errore

CarrierWave::IntegrityError in UsersController#create 
You are not allowed to upload "docx" files, allowed types: ["jpg", "jpeg", "gif", "png"] 

invece di normale errore di validazione dei form.

Come posso risolvere questo problema? Grazie !

+0

stai caricando un file immagine o un file di parole Microsoft? –

+0

ho bisogno di convalidare il tipo di file prima di caricarlo – AlphaB

+0

Si dovrebbe prendere il 'CarrierWave :: IntegrityError' o usare il metodo' store() '(senza!), Così come non lancia l'errore. –

risposta

3

In realtà ho risolto il mio problema. Ecco il codice di lavoro per le forme più fasi con upload di file utilizzando carrierwave

if params[:user][:img_path] 
    @uploaded = params[:user][:img_path] 
    params[:user].delete(:img_path) 
end 
session[:user_data].deep_merge!(params[:user]) if params[:user] 
@user = User.new(session[:user_data])  

if @uploaded 
    # here how validation will work 
    @user.img_path = @uploaded 
end 
@user.current_stage = session[:register_stage] 
if @user.valid? 
    if @user.last_stage? 
    @user.img_path = session[:img] if @user.last_stage? 
    @user.save 
    else 
    @user.next_stage 
    end 
    # now we can store carrierwave object in session 
    session[:img] = @user.img_path 
    session[:register_stage] = @user.current_stage 
end 
+0

Congratulazioni per la correzione!Quando sei in grado, assicurati di contrassegnare la tua risposta come "accettata" in modo che altri possano imparare dal tuo successo. Saluti ~ –

1

Questo può essere un po 'tardi per il PO, ma spero che questo aiuta qualcuno. Avevo bisogno di memorizzare un'immagine caricata nella sessione dell'utente (di nuovo per un modulo in più fasi), e anch'io ho iniziato con Ryan Railscast #217, ma l'applicazione si è rapidamente evoluta oltre. Si noti che il mio ambiente era Rails 4 su Ruby 2, utilizzando Carrierwave e MiniMagick, nonché activerecord-session_store, che spiegherò di seguito.

Credo che il problema che entrambi io e OP avevamo era che stavamo cercando di aggiungere tutti i parametri POST alla sessione dell'utente, ma con un caricamento di file, uno dei parametri era un oggetto UploadedFile, che è molto alla grande per quello. L'approccio descritto di seguito è un'altra soluzione a questo problema.

Disclaimer: Come è ampiamente noto, non è l'ideale per memorizzare oggetti complessi in sessione di un utente, meglio conservare gli identificatori di registrazione o altri dati identificativi (ad esempio il percorso di un'immagine) e cercare i dati quando necessario. Due motivi principali per questo mantenendo sincronizzati i dati di sessione e modello/database (un'attività non banale) e l'archivio di sessione di Rails predefinito (utilizzando i cookie) è limitato a 4kb.

mio modello (submission.rb):

class Submission < ActiveRecord::Base 
    mount_uploader :image_original, ImageUploader 
    # ... 
end 

Controller (submissions_controller.rb):

def create 
    # If the submission POST contains an image, set it as an instance variable, 
    # because we're going to remove it from the params 
    if params[:submission] && params[:submission][:image_original] && !params[:submission][:image_original].is_a?(String) 
    # Store the UploadedFile object as an instance variable 
    @image = params[:submission][:image_original] 
    # Remove the uploaded object from the submission POST params, since we 
    # don't want to merge the whole object into the user's session 
    params[:submission].delete(:image_original) 
    end 

    # Merge existing session with POST params 
    session[:submission_params].deep_merge!(params[:submission]) if params[:submission] 

    # Instantiate model from newly merged session/params 
    @submission = Submission.new(session[:submission_params]) 
    # Increment the current step in the session form 
    @submission.current_step = session[:submission_step] 

    # ... other steps in the form 

    # After deep_merge, bring back the image 
    if @image 
    # This adds the image back to the Carrierwave mounted uploader (which 
    # re-runs any processing/versions specified in the uploader class): 
    @submission.image_original = @image 
    # The mounted uploader now has the image stored in the Carrierwave cache, 
    # and provides us with the cache identifier, which is what we will save 
    # in our session: 
    session[:submission_params][:image_original] = @submission.image_original_cache 
    session[:image_processed_cached] = @submission.image_original.url(:image_processed) 
    end 

    # ... other steps in the form 

    # If we're on the last step of the form, fetch the image and save the model 
    if @submission.last_step? 
    # Re-populate the Carrierwave uploader's cache with the cache identifier 
    # saved in the session 
    @submission.image_original_cache = session[:submission_params][:image_original] 
    # Save the model 
    @submission.save 
    # ... render/redirect_to ... 
    end 
end 

Il mio file uploader è stato soprattutto scorta con qualche trattamento personalizzato.

Nota: per potenziare le sessioni, sto utilizzando activerecord-session_store, che è una gemma che è stata estratta dal nucleo di Rails nella v4 che fornisce un archivio di sessione supportato da database (aumentando così il limite della sessione di 4kb). Seguire the documentation per le istruzioni di installazione, ma nel mio caso è stato abbastanza veloce e indolore impostare e dimenticarlo. Nota per gli utenti con traffico elevato: i record della sessione rimanenti non sembrano essere eliminati dalla gemma, quindi se si riceve abbastanza traffico questa tabella potrebbe potenzialmente passare a un numero indicibile di righe.

+0

Stavo affrontando lo stesso problema. soluzione semplice Grazie – Anwar

Problemi correlati