RSS
 

Posts Tagged ‘Routes’

Gestire instradamenti errati

20 Nov

La nostra applicazione può rispondere solo a determinate richieste, naturalmente a quelle che abbiamo previsto. Per tutte le altre viene generato un errore in base al tipo:

  • Errori di instradamento
  • Errori nel controller

Errori di instradamento

Piccola premessa: In un’applicazione tradizionale, equivaleva a richiamare una pagina inesistente ricevendo dal web server un codice 404. In un framework con un pattern mvc, le richieste transitano attraverso un controller e questo ci permette di definirne il comportamento. Le richieste vengono smistate in base alle regole di instradamento ed in Rails, per convenzione, tutti i controllers possono essere indirizzati, in fondo al file routes.rb scopriamo il perchè:

#config\routes.rb
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'

Per fare in modo che solo determinati controllers possano essere instradati, basta eliminare quelle due righe in fondo al file che definiscono solo la forma della richiesta, lasciando solo gli instradamenti espliciti. Fine della premessa.

Se non esiste una rotta, viene generato un errore di instradamento (routing error) poichè Rails non sa cosa intendiamo richiamare. Per gestire questa evenienza, basta semplicemente aggiungere un’ultima strada prima di generare l’errore che percorrerà solo per informare che non ha trovato altre strade valide:

4
5
6
7
#config\routes.rb
 
#aggiungiamo in ultima riga, in coda a tutto
map.catch_all "*anything" , :controller => "home" , :action => "unknown_request"

Quest’ultima rotta cattura gli instradamenti non gestiti e li indirizza nel controller dove vogliamo gestirli, nell’esempio indirizza nel controller home col metodo unknown_request:

#app\controllers\home_controller.rb
def unknown_request
  respond_to do |format|
    format.html do
      flash[:error] = I18n.t(:unknown_request)
      redirect_to root_path
    end
    format.xml  {  render :xml => {:root => I18n.t(:unknown_request) }, :status => :unprocessable_entity }
  end
end

Errori nel controller

Se il controller è stato indirizzato non è detto che la richiesta sia comunque corretta, ognuno infatti ha una serie di operazioni che devono essere previste e devono poter operare sulla risorsa quindi gestire le eccezioni sollevate dal database.

Dalla versione 2.0 di rails, possiamo utilizzare rescue_from nel controller:

#app\controllers\my_controller.rb
 
class MyController < ApplicationController
  rescue_from ActionController::UnknownAction, :with => :action_not_found
  rescue_from ActiveRecord::RecordNotFound, :with => :record_not_found
 
  def action_not_found
    render 'shared/action_not_found', :layout => true, :status => 404
  end
  def record_not_found
    render 'shared/record_not_found', :layout => true, :status => 404
  end
end

Queste sono le viste:

#app\views\sharedaction _not_found.html.erb
<h2>Sorry, the action doesn't exists!</h2>
 
#app\views\sharedrecord_not_found.html.erb
<h2>Sorry, the record doesn't exists!</h2>

Usare una proc come parametro a rescue_from potrebbe essere un’alternativa più concisa:

#app\controllers\my_controller.rb
rescue_from(ActiveRecord::RecordNotFound) { |e| render 'shared/record_not_found', :layout => true, :status => 404 }
 
Comments Off

Posted in Ruby on Rails