Analisi del processo di inizializzazione del framework Ruby on Rails

Posted by Dibi Store Wed, 09 Jan 2008 08:22:00 GMT

Ruby on Rails è un framework di qui ho già sicuramente parlato molto, infatti ci lavoro fortunatamente ogni giorno a stretto contatto. Credo che chiunque lo abbia utilizzato almeno una volta abbia voluto sapere cosa succede realmente dietro le quinte di questa gemma. Per questo ho scritto questo articolo che descrive il processo di inizializzazione del framework. Per gli esempi prenderò come riferimento l'attuale versione 2.0.2 .

Innanzitutto consiglio per seguire meglio gli esempi di creare un progetto vuoto che chiameremo course, vi consiglio di tenere questo progetto sempre disponibile, in quanto verrà usato direttamente in articoli futuri. L'ultimo passo è quello di 'congelare' l'attuale versione di rails con il comando:

  rails course
  cd course/
  rake rails:freeze:gems

In alterativa potete scegliere il nome che volete, non ha particolare importanza. Aprendo il file config/database.yml, noterete subito che l'adattatore di default non è più mysql, bensì sqlite3. Ciò ci da un vantaggio immediato, infatti non abbiamo bisogno di andare a creare il database manualmente (anche se avremo potuto usare il comando rake db:create oppure rake db:create:all). A questo punto aprite il vostro IDE preferito, e iniziamo il nostro tour!

Il file dispatcher.rb dentro alla directory /public, è il primo che normalmente viene analizzato (in circostanze normali), nella prima riga vediamo che viene specificato come commento (un commento speciale a dire il vero) il percorso del nostro interprete. Ciò potrà non interessare a molti, ma ciò potrebbe dare in qualche modo fastidio alla macchina in qui effettuerete l'eventuale deploy (analizzeremo anche quello in futuro!) Sappiate che potete usare un trucchetto in molti casi, ossia dichiarare /usr/bin/env ruby, oppure dichiarare esplicitamente il percorso nel momento della generazione del progetto utilizzando l'opzione -r (provate in console a dare il comando rails -h se non lo avete mai fatto). Bando alle ciance, l'unica cosa importante è che viene 'richiesto' il file /config/environment.rb, ammeno che rails non sia gia stato inizializzato (non volete mica carica tutto il framework ogni volta, vero?).
Il file /config/environment.rb dapprima dichiara la versione di rails da utilizzare, poi caricherà il file boot.rb, che si trova nella stessa directory. Questo file dapprima definirà la variabile RAILS_ROOT che indicherò appunto la directory radice del progetto, dopodichè deciderà da dove andare a caricare il framework, in sostanza se è presente una directory /vendor/rails, il framework sarà caricato da li, altrimenti sarà caricato dalla vostra gemma presente nel sistema.

Qui possiamo notare una prima cosa interessante. Osservando il metodo preinitialize, all'incirca alla riga 29, potete notare che rails tenta di caricare un file, precisamente in /config/preinitializer.rb, ovviamente noi questo file andremo a crearlo (siamo [hacker|curiosi|non abbiamo un * da fare] o no?), e ci inseriremo il codice seguente, dopodichè avvieremo il server:

  puts "Ciao dal preinizializzatore!\n\n"
  
  # Salviamo e da console diamo:
  ./script/server
  
  dibistore:course oskar$ ./script/server
  Ciao dal preinizializzatore!

  => Booting Mongrel (use 'script/server webrick' to force WEBrick)
  => Rails application starting on http://0.0.0.0:3000
  => Call with -d to detach
  => Ctrl-C to shutdown server
  ** Starting Mongrel listening at 0.0.0.0:3000
  ** Starting Rails with development environment...
  ** Rails loaded.
  ** Loading any Rails specific GemPlugins
  ** Signals ready.  TERM => stop.  USR2 => restart.  INT => stop (no restart).
  ** Rails signals registered.  HUP => reload (without restart).  It might not work well.
  ** Mongrel 1.1.3 available at 0.0.0.0:3000
  ** Use CTRL-C to stop.
  

Fantastico, abbiamo appena scoperto un modo per inserire del codice ancora prima che venga caricato qualsiasi dato, questo apre molte possibilità, ma non è finita qui, infatti a questo punto caricheremo il file /vendor/rails/railties/lib/initializer.rb. Due parole per capire meglio: questa parte di rails, (railties) serve a collegare insieme i vari componenti (active record, action pack eccetera). Infatti nelle prime righe vengono impostate alcune costanti, aggiunti dei file alla load_path (tramite $LOAD_PATH.unshift File.dirname(__FILE__)) e dichiarato l'environment attuale (molto importante).
Il metodo che ora verrà chiamato è self.run, che potete ispezionare con calma, valutando le possibilità, poco sotto questo metodo vedete anche (commentato) l'elenco delle cose che vengono caricate da rails e il loro ordine, che qui traduco per semplicità:

  # * #controlla la versione di ruby (deve essere almeno la 1.2 ma non la 1.3)
  # * #inserisci i percorsi dei file nella load_path
  # * #carica i vari frameworks (active record ecc.)
  # * #inserisci altri percorsi nella load_path
  # * #aggiungi la directory dei plugin alla load_path (ma non li carica)
  # * #carica il file dell'environment corrente (/config/envrionments/whatever)
  # * #inizializza encoding
  # * #inizializza database (prepara connessione ecc.)
  # * #inizializza il logger
  # * #initializza e configura il logging dei vari frameworks
  # * #inizializza le viste dei frameworks
  # * #inizializza le dipendenze
  # * #inizializza whiny_nil (estende la class Nil, dandoci degli errori più utili)
  # * #inizializza directory temporanee
  # * #inizializza le configurazioni dei frameworks
  # * #aggiunge altri percorsi alla load_path
  # * #carica i plugins
  # * #carica gli observers (/config/initializers/)
  # * #inizializza il processo di routing
  # * #carica eventuali metodo definiti in /config/environment.rb chiamati after_initialize
  # * #carica il tutto

Il nome inizializzatore è più che azzecato, ovviamente non posso descrivere ora nel dettaglio ognuno di questi passi, per qui lo farò man mano nel tempo e pubblicherò degli articoli più dettagliati qui sul blog. Vi consiglio di continuare da soli a questo punto il processo di riscoperta dell'inizializzazione, in quanto è tempo sempre ripagato (che bello ruby).

Posted in  | Tags  | no comments | no trackbacks

Articoli interessanti e novità dell' ultima settimana

Posted by Dibi Store Thu, 22 Nov 2007 09:59:00 GMT

Libreria javascript per shourtcuts da tastiera

Oggi ho trovato una comoda libreria javascript, che ci permette di gestire le combinazioni da tastiera attraverso javascript, vi consiglio vivamente di dare un occhiata al link che contiene anche la documentazione e di non lasciarvi perdere questa gemma ( gemma != rubygems ).

Ruby API

Sarebbe bello avere a disposizione le api per ruby, rails, e magari per ruby gems, poi magari volete anche scaricarle nel vostro pc e che il tutto sia in ajax, e magari che il template utilizzato sia disponibile a tutti... Bhe magari vengo a portarvi anche un caffe!
Bhe non è uno scherzo, ecco a voi tutto questo: api rails e qui il sistema che è stato utilizzato! Si, lo so, mancano le api per le gemme, ma l'autore dice che saranno presto disponibili, qundi stay tuned!

Ultime news dal mondo ruby

Rubinius è un nuovo compilatore per ruby, potete scaricarne un anteprima dal sito del produttore, attraverso git (attendendo qualche ora) ma IMHO ne vale la pena. Potete trovare quache articolo interessante su questo blog o su questo. Comunque con una semplice ricerca su google troverete molti articoli a riguardo.

E' disponibile jrails, una nuova gemma che vi permette di usare jquery al posto di prototype & scriptaculous. Perchè? Innanzitutto perchè sembrerebbe che jquery sia più leggera e stia avendo successo. Perchè una gemma allora? Perchè altrimenti tutti gli helper forniti con rails non funzionerebbero più!

A dire il vero sarebbe anche da menzionare le nuove releases di jruby, l'implementazione di ruby in java, che sta riscuotendo molto interesse, io personalmente per ora non ci perdo tempo, vedete voi comunque se vi interessa.

Posted in  | Tags , ,  | no comments

Helper: button_to_remote

Posted by Dibi Store Fri, 19 Oct 2007 11:58:00 GMT

Siccome può tornare utile a molti, ho creato questo piccolo helper, in sostanza è un alias di button_to, solo che questo effettua una richiesta in remoto tramite AJAX.

Per usarlo è necessario solamente inserire il codice che trovate alla fine di questo articolo nel file application_helper.rb che si trova in app/helpers.
Usarlo è semplicissimo, infatti funziona esattamente come button_to, nell'esempio seguente simulo una richiesta ajax per eliminare un utente (utilizzando il formato rspec).

Read more...

Posted in  | Tags ,  | no comments

Un comodo plugin per creare in automatico Permalink con Rails

Posted by Dibi Store Sun, 23 Sep 2007 12:33:00 GMT

Oggi stavo cercando un modo semplice per costruire i miei permalink. Mi sono imbattuto in questo plugin molto semplice e utile.

Non servono spiegazioni dato che è semplicissimo da usare... Che dire: perchè scrivere codice quando è gia pronto?

Posted in  | Tags ,  | no comments

Personalizzare i messaggi di errore in ruby on rails

Posted by Dibi Store Sat, 22 Sep 2007 13:36:00 GMT

Ruby on rails è un framework eccezzionale. Tra i tanti vantaggi ci permette di gestire gli errori degli utenti nei form in un modo eccezzionale. L'unica pecca è che il framework è scritto in lingua inglese, e tutti i messaggi di errore sono ovviamente scritti in lingua anglosassone.

Ovviamente il rimedio esiste, ed è veramente semplice, vi basterà infatti aggiungere questo codice nel vostro modello:

validates_presence_of :name, :message => "Non può essere vuoto"
Read more...

Posted in  | Tags  | no comments

Creare select box dinamici con ruby on rails

Posted by Dibi Store Wed, 19 Sep 2007 19:58:00 GMT

A volte capita che dobbiamo creare dei select box dinamici nelle nostre applicazioni. L'esempio frequente è l'aggiunta di una categoria nella creazione di un prodotto.

Ipotizziamo di avere una tabella products in qui dobbiamo memorizzare un numero, che non è altro che l'identificativo del nome della categoria presente nella tabella products.

L'obiettivo è quindi quello di creare in modo dinamico una select box che abbia il seguente aspetto:

<select name="product[category_id]" id="product_category_id">
  <option value="1">categria1</option>
  <option value="2">categoria2</option>
</select>
Read more...

Posted in  | Tags ,  | 2 comments

Evidenziare i tab attivi con Ruby on Rails

Posted by Dibi Store Wed, 19 Sep 2007 09:53:00 GMT

Ormai tutti (o quasi) usiamo i tab per abbellire i nostri menu tramite CSS. Creare questi tab è facile e divertente, ci sono moltissimi esempi nella rete scaricabili gratuitamente.

Prendiamo ad esempio un segmento di file (x)html:

<ul>
  <li>tab1</li>
  <li>tab2</li>
  <li>tab3</li>
</ul>

Quello che vogliamo fare, è trovare un modo dinamico e flessibile per aggiungere una classe 'active' al tab attivo.

Read more...

Posted in  | Tags ,  | no comments

Quando create un url in rails, specificate sempre tutti i parametri.

Posted by Dibi Store Fri, 07 Sep 2007 12:19:00 GMT

Capita spesso di utilizzare il comodissimo formato link_to quando scriviamo le nostre applicazioni in rails.

Tutti sappiamo che come secondo parametro, possiamo specificare il controller, l'azione e gli eventuali parametri.

Read more...

Posted in  | Tags ,  | no comments

Il problema dei subcontroller in Rails

Posted by Dibi Store Fri, 31 Aug 2007 11:32:00 GMT

Se provate a creare un sub-controller in rails, ad esempio admin/setup, e provate ad inserire una qualsiasi azione, otterrete il seguente errore:

Unknown action

Per far funzionare correttamente il controller, ho dovuto editare manualmente il file routes.rb, inserendo il seguente codice:

Read more...

Posted in  | Tags ,  | no comments

Creare dei campi di modifica dinamici con l' InplaceEditor

Posted by Dibi Store Tue, 28 Aug 2007 22:06:00 GMT

Una delle cose che piu mi piace nelle applicazioni web 2.0, è la possibilità di poter aggiornare in tempo reale i nostri dati, semplicemente cliccando sul rispettivo valore.

Con ruby on rails e ajax, tutto questo è molto semplice

Read more...

Posted in  | Tags ,  | no comments