5

Scusate se la domanda è ovvia, sto solo iniziando a lavorare con Rails.
ho un seguente codice in diversi metodi di controller ora:Rails Newbie: raccomandazioni per la gestione degli errori nel controller

respond_to do |format| 
    if @project.save 
     format.html { redirect_to(edit_project_url(@project), :notice => '#{user.name} added to #{role}.') } 
     format.js 
    else 
     format.html { render :action => "edit" } 
     format.js #... 
    end 
end 

Quindi la domanda è, qual è il modo migliore per fare la stessa cosa per gli errori in tutti i metodi?
Si consiglia di utilizzare save! e gestirlo in rescue_action?

Oppure devo utilizzare il mio metodo respond e passare save in un blocco?

risposta

16

Spesso è più conveniente utilizzare la variante di salvataggio e salvataggio che si trova in un secondo momento nel blocco piuttosto che ramificarsi in quel modo. Il vantaggio delle eccezioni è che interrompono le transazioni.

def create 
    @project.save! 

    respond_to do |format| 
    format.html { redirect_to(edit_project_url(@project), :notice => '#{user.name} added to #{role}.') } 
    format.js 
    end 

rescue ActiveRecord::RecordInvalid 
    respond_to do |format| 
    format.html { render :action => "edit" } 
    format.js #... 
    end 
end 

Troverete che si fa veramente difficile da disputare la vostra via d'uscita da una pila di nidificate if dichiarazioni quando si cerca di salvare più di un oggetto alla volta, ma un semplice rescue per le eccezioni gestirà ordinatamente .

def create 
    Project.transaction do 
    @project.save! 
    @something_else.save! 
    @other_stuff.save! 
    end 

    # ... 
rescue ActiveRecord::RecordInvalid 
    # ... 
end 

Se uno di questi salva scoppi riceverai un'eccezione. Per garantire che tutti mostrino errori di convalida, è possibile che si debba chiamare .valid? su ognuno per innescarli o che si avranno quelli dopo che l'errore non è stato verificato.

+0

Questo sembra una buona idea, ma perché impalcatura non va in questo modo? Suppongo anche che tu raccomandi di usare 'rescue_action' se ci sono molti di questi metodi? –

+0

Ok, assumerò che intendessi un gestore di 'rescue_from' o' rescue_action_in_public' per più metodi, nel qual caso Chubas risponde qui è un sottoinsieme di questo e dovrei accettare questo come risposta. –

+0

Come regola generale uso 'rescue_from' per cose che non possono essere facilmente recuperate da, e' rescue' quando posso gestirle. Quando un 'create' fallisce, tipicamente si rende di nuovo il form' new'. Qualcosa di più astratto in genere restituisce una bella pagina "Uh oh". – tadman

3

Non è una brutta cosa usare il modello if @object.save. Tuttavia, se si sta facendo esattamente lo stesso per tutte le azioni sul controller, è possibile definire un'azione rescue_from.

Something like

class MyController < ActionController::Base 
    rescue_from ActiveRecord::RecordInvalid do 
    render :action => edit 
    end 
end 
+0

Sì, quella era una delle mie opzioni, ma questo tipo di versione di '!', Non è vero? Sai perché lo scaffold non va in questo modo di default? Mi sembra migliore. –

+0

Il tuo e e @tadman sembrano entrambi completarsi a vicenda, quindi accetterei entrambi se potessi, ma sfortunatamente ho dovuto sceglierne uno. –

Problemi correlati