Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Il flusso dell'applicazione

L'implementazione del pattern MVC in Ruby on Rails e prima navigazione del codice
L'implementazione del pattern MVC in Ruby on Rails e prima navigazione del codice
Link copiato negli appunti

Il pattern MVC fornisce delle linee guida per la suddivisione del codice in tre aree di competenza:

  • L'interazione con il database è di competenza del modello
  • L'interazione con l'utente è di competenza delle viste
  • La logica applicativa è di competenza del controller, che si occupa anche di fare da collante fra modello e viste

Lo scheletro dell'applicazione Rails e i file creati dal generatore scaffold seguono queste linee guida, così da permettere una navigazione agevole del codice; i modelli sono conservati nella cartelle app/models, le viste nella cartella app/views e i controller nella cartella app/controllers.

Avviamo il server dal terminale e puntiamo il browser all'indirizzo http://0.0.0.0:3000/bookmarks per ottenere l'elenco dei bookmark gestiti dall'applicazione. Cerchiamo di descrivere quello che è successo da quando abbiamo richiesto la pagina a quando la pagine è stata visualizzata:

  1. Il browser ha richiesto all'applicazione una pagina indicandone l'indirizzo
  2. L'applicazione ha ricevuto la richiesta, interpreta l'indirizzo per decidere quale controller e quale action attivare
  3. L'action ha estratto tutti i bookmark presenti nel database e li ha comunicati alla vista
  4. la vista ha visualizzato i bookmark generando la pagina HTML
  5. la pagina HTML è stata inviata al browser per la visualizzazione

Cerchiamo ora di ripercorrere questi step tenendo conto del codice della nostra applicazione. Capire il flusso interno dell'applicazione è utile per individuare il punto su cui intervenire per un eventuale modifica del codice, oltre che a comprendere i meccanismi interni di Rails.

Una volta ricevuta una richiesta dal client, l'applicazione deve individuare il controller e la action da attivare. Per effettuare questo collegamento l'applicazione consulta le regole di routing che conosce estraendole dal file di configurazione config/routes.rb.

Per avere una panoramica delle richieste attualmente riconosciute dalla nostra applicazione Rails e delle action attivate per ognuna di queste inseriamo dal terminale (dopo esserci assicurati di aver disattivato la console Rails) il comando rake routes.

$ rake routes
(in /Volumes/FIREFOX/html.it/bookmark_manager)
              bookmarks GET    /bookmarks                       {:action=>"index", :controller=>"bookmarks"}
    formatted_bookmarks GET    /bookmarks.:format               {:action=>"index", :controller=>"bookmarks"}
                        POST   /bookmarks                       {:action=>"create", :controller=>"bookmarks"}
                        POST   /bookmarks.:format               {:action=>"create", :controller=>"bookmarks"}
           new_bookmark GET    /bookmarks/new                   {:action=>"new", :controller=>"bookmarks"}
 formatted_new_bookmark GET    /bookmarks/new.:format           {:action=>"new", :controller=>"bookmarks"}
          edit_bookmark GET    /bookmarks/:id/edit              {:action=>"edit", :controller=>"bookmarks"}
formatted_edit_bookmark GET    /bookmarks/:id/edit.:format      {:action=>"edit", :controller=>"bookmarks"}
               bookmark GET    /bookmarks/:id                   {:action=>"show", :controller=>"bookmarks"}
     formatted_bookmark GET    /bookmarks/:id.:format           {:action=>"show", :controller=>"bookmarks"}
                        PUT    /bookmarks/:id                   {:action=>"update", :controller=>"bookmarks"}
                        PUT    /bookmarks/:id.:format           {:action=>"update", :controller=>"bookmarks"}
                        DELETE /bookmarks/:id                   {:action=>"destroy", :controller=>"bookmarks"}
                        DELETE /bookmarks/:id.:format           {:action=>"destroy", :controller=>"bookmarks"}
                               /:controller/:action/:id         
                               /:controller/:action/:id.:format 

Il risultato ottenuto a terminale indica in forma tabellare di tutte le regole di routing riconosciute dalla nostra applicazione, indicando in ordine:

  1. un'abbreviazione mnemonica della regola
  2. il metodo HTTP da utilizzare per la richiesta
  3. il path della richiesta
  4. il controller e l'action da attivare

Se apriamo il file config/routes.rb con un editor di testo notiamo l'istruzione map.resources :bookmarks, inserita automaticamente con dal generatore scaffold, che indica la presenza della risorsa Bookmarks e istruisce l'applicazione sulla presenza delle richieste necessarie per la manipolazione della risorsa.

La prima riga indica che la nostra richiesta, http://0.0.0.0:3000/bookmarks con il metodo GET, viene inoltrata al controller bookmarks per l'action index, e che la richiesta è denominata bookmarks. Nella seconda riga abbiamo una richiesta molto simile che riconosce la richiesta http://0.0.0.0:3000/bookmarks.xml utilizzata in una lezione precedente; in questo caso la regola di route custodisce nel parametro format il valore xml e lo rende disponibile al controller.

Apriamo quindi il file app/controllers/bookmarks.rb e concentriamoci sulla action index:

def index
  @bookmarks = Bookmark.find(:all)

  respond_to do |format|
    format.html # index.html.erb
    format.xml  { render :xml => @bookmarks }
  end
end

La prima istruzione che incontriamo è @bookmarks = Bookmark.find(:all), che estrae tutti i bookmark salvati nel database e li rende disponibili come array nella variabile @bookmarks. Bookmark è il nostro modello e quindi già nella prima istruzione possiamo vedere come il controller chiami in causa il modello per accedere ai dati persistenti nel database.

Terminata l'estrazione dei dati troviamo il blocco di codice che richiede l'intervento della vista. Osserviamo che nelle quattro righe del blocco respond_to viene indicata la possibilità di generare sia una pagina HTML (format.html) che un documento XML (format.xml).

Questa particolare funzionalità, introdotta nella versione 2.0 di Ruby on Rails, permette di generare viste differenti a partire da uno stesso controller, in base al formato richiesto (HTML, XML, JSON, CSV). Nel nostro caso è prevista la generazione di una pagina HTML per mezzo della vista abbinata alla action, e di un documento XML che rappresenta il contenuto della variabile @bookmarks in formato XML.

Diamo ora uno sguardo al codice che genera la pagina HTML. Secondo la convenzione Rails la vista abbinata ad una action ha come percorso:

app/views/<nome_controller>/<nome_vista>.<formato>.<sistema_template>

In questo caso siamo interessati alla vista abbinata al controller bookmarks, action index, formato HTML con sistema di template erb (il sistema di template standard di Rails); apriamo quindi con l'editor il file app/views/bookmarks/index.html.erb.

Il file contiene codice HTML, intervallato da codice Ruby che, racchiuso fra i delimitatori <% e %>, viene interpretato al momento della generazione della pagina. Una soluzione familiare a chi ha già dimestichezza con altri linguaggi lato server.

Esistono due tipi di tag per l'inclusione di codice Ruby; il tag <%=...%> viene utilizzato quando il risultato dell'esecuzione del codice Ruby deve essere stampato all'interno dell'HTML, mentre il tag <%...%> viene usato per cicli e condizioni come il for nella pagina che siamo osservando.

Nella vista è presente la variabile @bookmarks che non è definita all'interno della vista, ma che è stata definita nel controller. La vista ha quindi utilizzato il risultato espresso dal controller (l'estrazione dei dati dal database) per popolare la pagina HTML e restituirla al browser. Questa suddivisione dei compiti è tipica del pattern MVC: il codice che ha estratto i dati dal database si trova nel controller e non nella vista.

Se per applicazioni semplici come questa, l'utilizzo del pattern MVC sembra un esercizio di stile, al crescere dell'applicazione questo approccio favorisce la manutenibilità.

Ti consigliamo anche