2012-10-01 14 views
14

Ho un'app con utente ed eventi. Ogni utente ha diversi eventi. Quando un utente vuole vedere un evento specifico che si arriva a questa azione:come gestire ActiveRecord :: RecordNotFound nel controller di rails?

def show 
    begin 
    @userEvents = current_user.event 
    @event = @userEvents.find(params[:id]) 
    rescue ActiveRecord::RecordNotFound 
    redirect_to :controller => "main", :action => "index" 
    end 

    respond_to do |format| 
    format.html # show.html.erb 
    format.json { render json: @event } 
    end 
end 

Se l'evento non si trova per l'utente questo significa ha giocato con l'URL e l'evento che sta cercando di ottenere non appartiene a lui. Voglio o reindirizzare la pagina principale o semplicemente visualizzare la pagina con un errore che l'evento non è stato trovato. Se provo a eseguire il codice sopra questo errore si attiva:

AbstractController::DoubleRenderError in EventsController#show 

Qual è il modo migliore per risolvere questo problema?

risposta

20

Put tornare dopo reindirizzare

begin 
@userEvents = current_user.event 
@event = @userEvents.find(params[:id]) 
rescue ActiveRecord::RecordNotFound 
redirect_to :controller => "main", :action => "index" 
return 
end 
+0

oh dio grazie .... invio messaggio dal futuro =) –

14

Calling redirect_to non restituisce dal metodo di azione che è il motivo per passare al blocco respond_to provoca la DoubleRenderError. Un modo per risolvere il problema che è con:

redirect_to :controller => "main", :action => "index" and return 

Tuttavia, una soluzione migliore potrebbe essere quella sia rescue from questa eccezione in modo dichiarativo o semplicemente lasciare che si propagano al cliente. L'ex simile a questa:

class YourController < ActionController::Base 

    rescue_from ActiveRecord::RecordNotFound, with: :dude_wheres_my_record 

    def show 
    # your original code without the begin and rescue 
    end 

    def dude_where_my_record 
    # special handling here 
    end 
end 

Se hai appena lasciato l'eccezione fester l'utente vedrà la pagina di public/404.html in modalità di produzione.

+0

non ha capito la tua soluzione ... perché questo salvataggio si verifica ogni volta nel controller? .. ho bisogno solo nel mostrare azione. ma grazie –

+0

Il 'rescue_from' è solo un modo più gentile di gestire gli errori comuni, a volte, consentendo di separare i problemi nel codice. Ovviamente non è sempre meglio, quindi le altre due opzioni :-) – noodl

+0

THanks .... ha funzionato anche per me =) –

5

In un controllore di applicazione, si prega di scrivere:

rescue_from (ActiveRecord::RecordNotFound) { |exception| handle_exception(exception, 404) } 

    protected 

    def handle_exception(ex, status) 
     render_error(ex, status) 
     logger.error ex 
    end 

    def render_error(ex, status) 
     @status_code = status 
     respond_to do |format| 
      format.html { render :template => "error", :status => status } 
      format.all { render :nothing => true, :status => status } 
     end 
    end 

creare una pagina error.html.erb

<div class="page-header"> 
    <h1> 
    <%= t "errors.#{@status_code}.heading" %> 
    <small><%= t "errors.#{@status_code}.subheading" %></small> 
    </h1> 
</div> 
<p><%= t "errors.#{@status_code}.description" %></p> 
<% if defined? root_path %> 
    <%= link_to t(:return_to_home), root_path %> 
<% end %> 

e in en.yml

+0

Nota rapida, error.htm.erb dovrebbe andare all'interno della directory/views root. –

Problemi correlati