<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description></description><title>ateapick</title><generator>Tumblr (3.0; @ateapick)</generator><link>http://blog.ateapick.com/</link><item><title>Unobtrusive JavaScript...&amp; friends</title><description>&lt;p&gt;Con il termine &lt;a href="http://en.wikipedia.org/wiki/Unobtrusive_JavaScript"&gt;Unobtrusive JavaScript&lt;/a&gt; (JavaScript non intrusivo) si indica un paradigma di programmazione JavaScript che si basa su 3 principi fondamentali:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.alistapart.com/articles/behavioralseparation"&gt;Behavioral Separation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://javascript.html.it/articoli/leggi/2194/graceful-degradation-e-progressive-enhancement/"&gt;Graceful degradation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://javascript.html.it/articoli/leggi/2194/graceful-degradation-e-progressive-enhancement/3/"&gt;Progressive enhancement&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Senza la pretesa di voler dare una spiegazione esaustiva per ognuno dei precedenti principi, cerchiamo di capire in termini pratici cosa significa e, soprattutto, perchè scrivere JavaScript non intrusivo porta vantaggi concreti nello sviluppo e nella manutenzione di un’applicazione web.&lt;/p&gt;
&lt;p&gt;I passi da seguire sono essenzialmente i seguenti:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Scrivere pagine &lt;span class="caps"&gt;HTML&lt;/span&gt; funzionanti &lt;strong&gt;senza l’utilizzo di JavaScript&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Aggiungere funzioni JavaScript agli elementi del &lt;span class="caps"&gt;DOM&lt;/span&gt; &lt;strong&gt;senza modificare l’&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Facciamo un semplice esempio per evidenziare la differenza tra l’approccio “classico” e l’approccio non intrusivo. Supponiamo di avere un link di questo tipo:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
    &amp;lt;a href="#" onclick="alert('hallo!');"&amp;gt;say hallo&amp;lt;/a&amp;gt;
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;E’ evidente come un browser con JavaScript disabilitato non riceverebbe alcun saluto :) Aggiungiamo pertanto un link alla pagina &lt;em&gt;hallo.html&lt;/em&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
    &amp;lt;a href="hallo.html" onclick="alert('hallo!'); return false;"&amp;gt;say hallo&amp;lt;/a&amp;gt;
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;In questo esempio, migliorato rispetto al precedente, i browser senza JavaScript seguirebbero il link alla pagina &lt;em&gt;hallo.html&lt;/em&gt; mentre i browser con JavaScript vedrebbero aprirsi l’alert. Un ulteriore miglioramento all’esempio può essere apportato eliminando ogni riga di codice JavaScript dalla pagina spostandolo in un file esterno (&lt;em&gt;hallo.js&lt;/em&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
    &amp;lt;script src="hallo.js" type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;a href="hallo.html" id="hallo_link"&amp;gt;say hallo&amp;lt;/a&amp;gt;
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Il file &lt;em&gt;hallo.js&lt;/em&gt; conterrà una funzione che, al caricamento della pagina, assegnerà all’evento &lt;em&gt;click&lt;/em&gt; dell’elemento identificato da &lt;em&gt;hallo_link&lt;/em&gt; la funzione per la generazione dell’alert. In altre parole: abbiamo modificato il nostro link mantenendo la stessa funzionalità ma in modo &lt;strong&gt;non intrusivo&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;Vantaggi&lt;/h3&gt;
&lt;p&gt;Questo tipo di sviluppo necessita di una disciplina che può sembrare eccessivamente impegnativa rispetto ai vantaggi concreti che porta. Ammetto che in passato, come molti sviluppatori, ho deciso spesso di sacrificare l’accessibilità delle pagine in virtù della considerazione che oggi la stragrande maggioranza dei browser supporta JavaScript, per cui è accettabile rinunciare ad una completa compatibilità.&lt;/p&gt;
&lt;p&gt;In qualità di sviluppatore Rails, inoltre, non ho mai pensato di rinunciare ai comodi helper offerti dal framework per il wrapping delle funzioni di &lt;a href="http://www.prototypejs.org/"&gt;prototype&lt;/a&gt; e &lt;a href="http://script.aculo.us/"&gt;scriptaculous&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Tutto questo finchè non ho adottato in maniera continuativa una metodologia di sviluppo “Behavior Driven” (&lt;a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development"&gt;&lt;span class="caps"&gt;BDD&lt;/span&gt;&lt;/a&gt;) con &lt;a href="http://cukes.info/"&gt;Cucumber&lt;/a&gt; e &lt;a href="http://github.com/brynary/webrat"&gt;Webrat&lt;/a&gt; ed ho iniziato a considerare seriamente le linee guida dettate dal &lt;a href="http://it.wikipedia.org/wiki/Ottimizzazione_%28motori_di_ricerca%29"&gt;&lt;span class="caps"&gt;SEO&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Sia &lt;em&gt;Webrat&lt;/em&gt; che i &lt;em&gt;crawler&lt;/em&gt; dei motori di ricerca, infatti, possono essere considerati (se pur con delle eccezioni) come browser che non supportano JavaScript. La programmazione non intrusiva, quindi, mi permette di eseguire senza problemi i test di &lt;em&gt;cucumber&lt;/em&gt; e di mantenere le pagine ottimizzate per l’indicizzazione. Come “effetto collaterale”, inoltre, le pagine così scritte sono accessibili e sicuramente più leggibili.&lt;/p&gt;
&lt;p&gt;Questi vantaggi rappresentano per me una motivazione più che valida per abbandonare il codice intrusivo prodotto dagli helper di Rails in favore dell’alternativa non intrusiva rappresentata dall’ottimo &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;jQuery on Rails&lt;/h3&gt;
&lt;p&gt;Per utilizzare jQuery con Rails esistono 2 alternative: la prima consiste nell’utlizzare &lt;a href="http://code.google.com/p/ennerchi/"&gt;jRails&lt;/a&gt; che essenzialmente riscrive (quasi) tutti gli helper di Rails per l’utilizzo con jQuery al posto di prototype e scriptaculous. Questa soluzione a mio avviso non è molto valida, poichè il codice prodotto sarà comunque intrusivo. Non resta quindi che scrivere JavaScript con jQuery senza l’utilizzo di alcun helper. Anche &lt;strong&gt;Ryan Bates&lt;/strong&gt; incoraggia la seconda strada in uno dei suoi preziosi &lt;a href="http://railscasts.com/episodes/136-jquery"&gt;screencast&lt;/a&gt;: sarà necessario qualche sforzo in più ma alla fine il tempo impiegato sarà tutt’altro che sprecato.&lt;/p&gt;</description><link>http://blog.ateapick.com/post/1166241672</link><guid>http://blog.ateapick.com/post/1166241672</guid><pubDate>Wed, 30 Sep 2009 10:05:00 +0200</pubDate><category>accessibilità</category><category>bdd</category><category>seo</category><category>unobtrusive</category><category>javascript</category><dc:creator>dando76</dc:creator></item><item><title>Login centralizzato tra applicazioni Rails</title><description>&lt;p&gt;In un &lt;a href="http://www.ateapick.com/blog/login-centralizzato-con-il-protocollo-cas"&gt;articolo precedente&lt;/a&gt; ho affrontato la questione del &lt;strong&gt;login centralizzato tra più applicazioni&lt;/strong&gt; attraverso il protocollo &lt;a href="http://en.wikipedia.org/wiki/Central_Authentication_Service"&gt;&lt;span class="caps"&gt;CAS&lt;/span&gt;&lt;/a&gt; (Central Authentication Service). La soluzione presentata risulta una buona scelta nel momento in cui si debba gestire un’autenticazione comune tra applicazioni eternogenee, web o desktop, scritte in Rails, Java, &lt;span class="caps"&gt;PHP&lt;/span&gt;, Python o .NET.&lt;/p&gt;
&lt;p&gt;Se però consideriamo una &lt;em&gt;suite&lt;/em&gt; di applicazioni sviluppate in &lt;strong&gt;Ruby on Rails&lt;/strong&gt; su uno &lt;strong&gt;stesso dominio&lt;/strong&gt;, possiamo “giocare” con la gestione delle sessioni per condividere le credenziali degli utenti tra le applicazioni della &lt;em&gt;suite&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Tipicamente, infatti, il controllo degli accessi viene implementato attraverso il salvataggio in sessione di un identificativo dell’utente, in seguito all’inserimento da parte di quest’ultimo di username e password validi. La condivisione dell’autenticazione, quindi, si riconduce alla &lt;strong&gt;condivisione delle sessioni&lt;/strong&gt; tra le applicazioni.&lt;/p&gt;
&lt;h3&gt;Rails e le sessioni&lt;/h3&gt;
&lt;p&gt;In Rails una sessione è una struttura &lt;strong&gt;simile&lt;/strong&gt; ad un hash (coppie chiave-valore) che permette di rendere persistenti i dati tra una richiesta e l’altra. In sessione può essere salvato ogni tipo di dato, dal momento in cui questi vengono &lt;a href="http://it.wikipedia.org/wiki/Serializzazione"&gt;serializzati&lt;/a&gt; in una delle seguenti opzioni di storage:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;CookieStore (default)&lt;/li&gt;
&lt;li&gt;ActiveRecordStore&lt;/li&gt;
&lt;li&gt;SQLSessionStore&lt;/li&gt;
&lt;li&gt;&lt;span class="caps"&gt;DRBS&lt;/span&gt;tore&lt;/li&gt;
&lt;li&gt;MemCacheStore&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;I criteri di scelta del tipo di &lt;em&gt;session storage&lt;/em&gt; variano in funzione dei requisiti di spazio, sicurezza e performance. La soluzione basata sui cookie, ad esempio, è caratterizzata da un limite di storage di 4K ma da una velocità molto superiore rispetto alle altre. Questo è il motivo per cui è stata scelta come opzione di default. L’integrità dei dati è supportata dalla crittazione delle informazioni attraverso un algoritmo di &lt;a href="http://en.wikipedia.org/wiki/Hash_algorithm"&gt;digest&lt;/a&gt; (SHA1) e una &lt;strong&gt;chiave segreta&lt;/strong&gt; univoca per ogni applicazione. Due applicazioni, quindi, condividono la stessa sessione se condividono la stessa chiave.&lt;/p&gt;
&lt;h3&gt;Login centralizzato&lt;/h3&gt;
&lt;p&gt;Consideriamo una &lt;em&gt;suite&lt;/em&gt; di applicazioni identificate da sottodomini diversi dello stesso dominio:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;app1&lt;/strong&gt;.example.com&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;app2&lt;/strong&gt;.example.com&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;app3&lt;/strong&gt;.example.com&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Per fare in modo che le applicazioni condividano la sessione, è sufficiente specificare in ogni &lt;em&gt;environment.rb&lt;/em&gt; la stessa configurazione:&lt;/p&gt;

&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="source source_ruby"&gt;config&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;action_controller&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;session &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby"&gt;{&lt;/span&gt;&lt;span class="meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block"&gt;
&lt;/span&gt;&lt;span class="linenum"&gt; 2&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;session_key&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;_example_session&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt;
&lt;span class="linenum"&gt; 3&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;secret&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;shared_secret_long_string&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 4&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby"&gt;}&lt;/span&gt;
&lt;span class="linenum"&gt; 5&lt;/span&gt; 
&lt;span class="linenum"&gt; 6&lt;/span&gt; &lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby"&gt;#&lt;/span&gt; rails 2.3
&lt;/span&gt;&lt;span class="linenum"&gt; 7&lt;/span&gt; config&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;action_controller&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;session&lt;span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby"&gt;[&lt;/span&gt;&lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;domain&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby"&gt;]&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;.example.com&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 8&lt;/span&gt; 
&lt;span class="linenum"&gt; 9&lt;/span&gt; &lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby"&gt;#&lt;/span&gt; per le versioni di rails precedenti alla 2.3
&lt;/span&gt;&lt;span class="linenum"&gt; 10&lt;/span&gt; &lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby"&gt;#&lt;/span&gt; ActionController::Base.session_options[:session_domain] = '.example.com'&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Supponiamo che &lt;strong&gt;app1&lt;/strong&gt; contenga il model &lt;em&gt;User&lt;/em&gt; e la logica di autenticazione. Una volta effettuato l’accesso, anche &lt;strong&gt;app2&lt;/strong&gt; e &lt;strong&gt;app3&lt;/strong&gt; vedono lo stesso &lt;em&gt;user_id&lt;/em&gt; in sessione. A questo punto basta definire in &lt;strong&gt;app1&lt;/strong&gt; e &lt;strong&gt;app2&lt;/strong&gt; il model &lt;em&gt;User&lt;/em&gt; connesso al database di &lt;strong&gt;app1&lt;/strong&gt;:&lt;/p&gt;

&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="source source_ruby"&gt;&lt;span class="meta meta_class meta_class_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_class keyword_control_class_ruby"&gt;class&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby"&gt;User&lt;span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby"&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_inheritance punctuation_separator_inheritance_ruby"&gt;&amp;lt;&lt;/span&gt; ActiveRecord::Base&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 2&lt;/span&gt; &lt;span class="variable variable_language variable_language_ruby"&gt;self&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;abstract_class &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="constant constant_language constant_language_ruby"&gt;true&lt;/span&gt; 
&lt;span class="linenum"&gt; 3&lt;/span&gt; establish_connection&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;
&lt;span class="linenum"&gt; 4&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;adapter&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;mysql&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt;
&lt;span class="linenum"&gt; 5&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;host&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;localhost&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt;
&lt;span class="linenum"&gt; 6&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;username&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;ateapick&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt;
&lt;span class="linenum"&gt; 7&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;password&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;supersecret&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt;
&lt;span class="linenum"&gt; 8&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;database&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;app1&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 9&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt; 
&lt;span class="linenum"&gt; 10&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;h3&gt;Un caso di studio: formula-brake.com&lt;/h3&gt;
&lt;p&gt;Di recente abbiamo implementato un’autenticazione centralizzata su una serie di webapp aziendali per &lt;a href="http://www.formula-brake.com"&gt;Formula&lt;/a&gt;, uno dei nostri clienti. In particolare, una delle applicazioni (&lt;strong&gt;security&lt;/strong&gt;.formula-brake.com) ha un’area riservata per la gestione di tutti gli utenti aziendali e dei loro privilegi ed una parte pubblica che funge da &lt;strong&gt;gateway di autenticazione&lt;/strong&gt; per tutte le altre applicazioni.&lt;/p&gt;
&lt;p&gt;Per la gestione delle sessioni utente abbiamo utilizzato &lt;a href="http://github.com/binarylogic/authlogic/tree/master"&gt;authlogic&lt;/a&gt;, un’ottima gemma realizzata dal bravissimo Ben Johnson di &lt;a href="http://www.binarylogic.com/"&gt;Binary Logic&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Per passare da una webapp all’altra, esiste infine un &lt;strong&gt;header condiviso&lt;/strong&gt; con i link a tutte le applicazioni della &lt;em&gt;suite&lt;/em&gt;, sulla falsa riga di quello presente su &lt;a href="http://www.google.it/"&gt;Google&lt;/a&gt;.&lt;/p&gt;</description><link>http://blog.ateapick.com/post/1166254293</link><guid>http://blog.ateapick.com/post/1166254293</guid><pubDate>Thu, 18 Jun 2009 00:00:00 +0200</pubDate><category>login</category><category>rails</category><category>ruby</category><category>soluzioni</category><category>webapp</category><dc:creator>dando76</dc:creator></item><item><title>Localizzazione URL in Ruby on Rails</title><description>&lt;p&gt;Quando si parla di &lt;a href="http://it.wikipedia.org/wiki/Internazionalizzazione_e_localizzazione"&gt;internazionalizzazione e localizzazione&lt;/a&gt; delle applicazioni web spesso non viene data la giusta importanza alla localizzazione degli indirizzi, aspetto fondamentale in termini di &lt;a href="http://en.wikipedia.org/wiki/Search_engine_optimization"&gt;&lt;span class="caps"&gt;SEO&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A partire da Rails 2.2 è stato aggiunto al framework il &lt;a href="http://guides.rubyonrails.org/i18n.html"&gt;supporto nativo&lt;/a&gt; a &lt;strong&gt;I18n&lt;/strong&gt; e &lt;strong&gt;L10n&lt;/strong&gt; con una gestione delle traduzioni e delle regole di localizzazione (date, valute etc.) basata su file &lt;strong&gt;.yml&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Al supporto nativo mancano ancora 2 aspetti a mio parere importanti:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;La localizzazione dei &lt;strong&gt;contenuti&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;La localizzazione degli &lt;strong&gt;indirizzi&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Per quanto riguarda i contenuti continuo ad usare con soddisfazione il mio &lt;a href="http://www.ateapick.com/blog/alternativa-a-globalize"&gt;Model Localization Plugin&lt;/a&gt; riadattato in maniera molto semplice dall’utilizzo di &lt;strong&gt;GetText.locale&lt;/strong&gt; a &lt;strong&gt;I18n.locale&lt;/strong&gt; per l’identificazione della lingua corrente.&lt;/p&gt;
&lt;p&gt;Per la localizzazione degli indirizzi ho di recente provato il &lt;a href="http://github.com/raul/translate_routes/tree/master"&gt;translate_routes plugin&lt;/a&gt; che permette l’internazionalizzazione di tutti gli indirizzi dell’applicazione &lt;strong&gt;con una sola riga di codice&lt;/strong&gt; oltre, ovviamente, alle traduzioni stesse su file &lt;strong&gt;.yml&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;Localizzazione degli indirizzi&lt;/h3&gt;
&lt;p&gt;Supponiamo di avere una webapp in lingua inglese ed una risorsa &lt;em&gt;project&lt;/em&gt; identificata da indirizzi del tipo:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.example.com/"&gt;http://www.example.com/&lt;/a&gt; &lt;strong&gt;projects&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.example.com/"&gt;http://www.example.com/&lt;/a&gt; &lt;strong&gt;projects&lt;/strong&gt; / my-great-project&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;L’utilizzo del plugin permette di aggiungere le route seguenti:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.example.com/"&gt;http://www.example.com/&lt;/a&gt; &lt;strong&gt;it&lt;/strong&gt; / &lt;strong&gt;progetti&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.example.com/"&gt;http://www.example.com/&lt;/a&gt; &lt;strong&gt;it&lt;/strong&gt; / &lt;strong&gt;progetti&lt;/strong&gt; / my-great-project&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Per completare la localizzazione basta gestire la traduzione dei &lt;strong&gt;permalink&lt;/strong&gt; sul database (localizzazione dei contenuti) per avere:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.example.com/"&gt;http://www.example.com/&lt;/a&gt; &lt;strong&gt;it&lt;/strong&gt; / &lt;strong&gt;progetti&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.example.com/"&gt;http://www.example.com/&lt;/a&gt; &lt;strong&gt;it&lt;/strong&gt; / &lt;strong&gt;progetti&lt;/strong&gt; / &lt;strong&gt;il-mio-grande-progetto&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Da notare come la linua base (in questo caso l’inglese) non abbia bisogno del prefisso &lt;em&gt;en&lt;/em&gt;. Questo significa che nel momento in cui decidiamo di aggiungere il supporto multi-lingua alla nostra applicazione, tutti i “vecchi” indirizzi rimangono inalterati.&lt;/p&gt;</description><link>http://blog.ateapick.com/post/1166264542</link><guid>http://blog.ateapick.com/post/1166264542</guid><pubDate>Sun, 14 Jun 2009 00:00:00 +0200</pubDate><category>i10n,</category><category>plugin,</category><category>i18n</category><category>indirizzi</category><category>internazionalizzazione</category><category>localizzazione</category><category>seo</category><category>url</category><category>rails</category><category>ruby</category><dc:creator>dando76</dc:creator></item><item><title>Backup incrementali su Amazon Simple Storage Service (Amazon S3)</title><description>&lt;p&gt;In Informatica il &lt;a href="http://it.wikipedia.org/wiki/Backup"&gt;backup&lt;/a&gt; dei dati è una buona abitudine da adottare in ambito domestico ed una pratica che diventa assolutamente doverosa quando si passa alla sfera professionale.&lt;/p&gt;
&lt;p&gt;Per le nostre &lt;strong&gt;applicazioni web&lt;/strong&gt; abbiamo scelto una soluzione che prevede il backup giornaliero sui Server di &lt;a href="http://www.amazon.com/"&gt;Amazon&lt;/a&gt; attraverso il servizio denominato &lt;a href="http://aws.amazon.com/s3/"&gt;Amazon Simple Storage Service&lt;/a&gt; o, più semplicemente, &lt;strong&gt;Amazon S3&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;L’iscrizione al servizio è gratuita e prevede un &lt;a href="http://aws.amazon.com/s3/#pricing"&gt;costo a consumo&lt;/a&gt; molto basso a fronte di un’elevata affidabilità.&lt;/p&gt;
&lt;p&gt;La scelta di effettuare i backup su server remoti presenta indubbi vantaggi in termini di &lt;strong&gt;sicurezza&lt;/strong&gt; ma ha un’inevitabile controindicazione legata alla &lt;strong&gt;lentezza&lt;/strong&gt; con cui avvengono i processi di copia, soprattutto per grandi quantità di dati. Per ottimizzare le prestazioni (e i costi) effettuiamo &lt;strong&gt;backup incrementali&lt;/strong&gt;, attraverso la sincronizzazione dei dati tra lo storage locale e lo storage remoto.&lt;/p&gt;
&lt;p&gt;La scelta del protocollo di sincronizzazione è ricaduta sull’ottimo &lt;a href="http://www.samba.org/rsync/"&gt;rsync&lt;/a&gt; che, affiancato a &lt;a href="http://code.google.com/p/s3fs/wiki/FuseOverAmazon"&gt;s3fs&lt;/a&gt;, permette in pochi minuti di configurare il proprio &lt;a href="http://www.ubuntu-it.org/index.php?page=server"&gt;server linux&lt;/a&gt; e dormire sonni tranquilli :)&lt;/p&gt;
&lt;h3&gt;Configurazione del backup&lt;/h3&gt;
&lt;p&gt;Supponiamo di voler configurare il backup del database e dei dati dell’applicazione &lt;strong&gt;myapp&lt;/strong&gt; secondo il seguente scenario:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;i dati risiedono nella directory &lt;em&gt;/var/apps/myapp&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;il database (mysql) si chiama &lt;em&gt;myapp_db&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;avete creato una directory per il backup locale in &lt;em&gt;/var/backups/myapp&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;il vostro userid Amazon è &lt;em&gt;s3uid&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;la vostra password Amazon è &lt;em&gt;s3pwd&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;avete creato il bucket &lt;em&gt;myapp_bucket&lt;/em&gt; su Amazon&lt;/li&gt;
&lt;li&gt;avete creato la directory &lt;em&gt;/mnt/s3&lt;/em&gt; dove verrà montato il bucket&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;L’idea è quella di sincronizzare i dati ed effettuare il dump del database nella diretory di backup locale, montare il &lt;em&gt;bucket&lt;/em&gt; tramite s3fs ed effettuare la sincronizzazione tra &lt;em&gt;/var/backup/myapp&lt;/em&gt; e &lt;em&gt;/mnt/s3&lt;/em&gt; tramite rsync.&lt;/p&gt;
&lt;p&gt;Il passaggio di sincronizzazione intermedio è utile per &lt;strong&gt;minimizzare il tempo di inattività&lt;/strong&gt; di &lt;em&gt;myapp&lt;/em&gt; che dovrà essere opportunamente sospesa durante la prima fase di backup (locale) onde evitare incongruenze sul database.&lt;/p&gt;
&lt;h3&gt;Creazione dello script&lt;/h3&gt;
&lt;p&gt;Sulla base dello scenario che abbiamo preso come esempio, lo script di sincronizzazione sarà del tipo seguente:&lt;/p&gt;
&lt;p&gt;#!/bin/bash&lt;br/&gt;&lt;strong&gt;sospendi myapp&lt;/strong&gt;&lt;br/&gt; rsync -avzO —delete /var/apps/myapp /var/backups/myapp&lt;br/&gt; mysqldump —user=xxx —password=xxx myapp_db &amp;gt; /var/backups/myapp/dump.sql&lt;br/&gt;&lt;strong&gt;riattiva myapp&lt;/strong&gt;&lt;br/&gt; s3fs myapp_bucket -o accessKeyId=s3uid -o secretAccessKey=s3pwd /mnt/s3&lt;br/&gt; rsync -avzO —delete /var/backups/myapp /mnt/s3&lt;br/&gt; umount /mnt/s3&lt;/p&gt;
&lt;p&gt;A questo punto basta automatizzare lo script mettendolo in &lt;a href="http://it.wikipedia.org/wiki/Crontab"&gt;crontab&lt;/a&gt; e il gioco è fatto. Ricordatevi di controllare la correttezza dei permessi su tutti i file e le directory.&lt;/p&gt;</description><link>http://blog.ateapick.com/post/1166269375</link><guid>http://blog.ateapick.com/post/1166269375</guid><pubDate>Sat, 28 Mar 2009 00:00:00 +0100</pubDate><category>amazon</category><category>backup</category><category>linux</category><category>rsync</category><category>s3</category><dc:creator>dando76</dc:creator></item><item><title>Login centralizzato con il protocollo CAS</title><description>&lt;p&gt;Per “login centralizzato” si intende la condivisione da parte di più applicazioni web di un servizio di autenticazione degli utenti che garantisca l’acesso ad ogni applicazione attraverso un’unica login.&lt;/p&gt;
&lt;p&gt;Consideriamo alcuni scenari:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;La Intranet di un’azienda è dotata di una serie di applicazioni web ad accesso protetto i cui utenti devono essere autenticati attraverso il servizio di &lt;a href="http://it.wikipedia.org/wiki/Active_Directory"&gt;Active Directory&lt;/a&gt; con il quale vengono gestiti gli accessi di tutte le altre applicazioni aziendali.&lt;/li&gt;
&lt;li&gt; Un’organizzazione vuol pubblicare su Internet alcune applicazioni o siti web ad accesso condiviso (vd. &lt;a href="http://www.google.com/apps"&gt;Google Apps&lt;/a&gt; ) in modo che un utente, una volta eseguito l’accesso su una qualsiasi delle applicazioni, possa accedere a tutte le altre senza dover inserire nuovamente username e password.&lt;/li&gt;
&lt;li&gt;In una &lt;span class="caps"&gt;SOA&lt;/span&gt; (Service-Oriented Architecture) alcuni Web Sevice devono comunicare con gli altri attraverso l’&lt;span class="caps"&gt;HTTP&lt;/span&gt; e condividere le credenziali per poterlo fare.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Come possiamo implementare un sistema di autenticazione centralizzata in questi (eterogenei) scenari? Prendiamo in considerazione &lt;strong&gt;una delle possibili soluzioni&lt;/strong&gt;: l’utilizzo di un servizio basato sul protocollo &lt;a title="Central Authentication Service" href="http://en.wikipedia.org/wiki/Central_Authentication_Service"&gt;&lt;span class="caps"&gt;CAS&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Central Authentication Service (&lt;span class="caps"&gt;CAS&lt;/span&gt;)&lt;/h3&gt;
&lt;p&gt;Sviluppato dall’Università di Yale e diventato nel 2004 un progetto &lt;a href="http://www.ja-sig.org/products/cas/"&gt;JA-&lt;span class="caps"&gt;SIG&lt;/span&gt;&lt;/a&gt;, &lt;span class="caps"&gt;CAS&lt;/span&gt; è un protocollo divenuto abbastanza maturo ed utilizzato; il suo funzionamento di base prevede &lt;strong&gt;un server ed un client&lt;/strong&gt; ed è rappresentato dallo schema seguente:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l953cvdgYs1qcqixx.png"/&gt;&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;L’utente tenta di accedere ad una pagina protetta&lt;/li&gt;
&lt;li&gt;Il &lt;span class="caps"&gt;CAS&lt;/span&gt; client reindirizza il browser alla pagina di login sul &lt;span class="caps"&gt;CAS&lt;/span&gt; server&lt;/li&gt;
&lt;li&gt;Il &lt;span class="caps"&gt;CAS&lt;/span&gt; server valida username e password su un &lt;strong&gt;datasource&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Il browser viene rimandato alla pagina richiesta inizialmente con un &lt;strong&gt;service ticket&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Il &lt;strong&gt;service ticket&lt;/strong&gt; garantisce la persistenza delle credenziali su tutte le altre applicazioni&lt;/li&gt;
&lt;/ol&gt;&lt;h3&gt;Datasource&lt;/h3&gt;
&lt;p&gt;La forza di questo protocollo risiede nella possibilità di utilizzare qualsiasi datasource per la gestione degli utenti. Può essere usato un &lt;span class="caps"&gt;DBMS&lt;/span&gt;, Active Directory, un servizio &lt;a href="http://it.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol"&gt;&lt;span class="caps"&gt;LDAP&lt;/span&gt;&lt;/a&gt;, un file &lt;span class="caps"&gt;XML&lt;/span&gt; etc. &lt;strong&gt;Gli utenti possono essere addirittura autenticati con i propri account Gmail&lt;/strong&gt;. Il controllo può essere anche effettuato su più datasource ordinati per priorità: ad esempio possiamo controllare le credenziali dell’utente sul un nostro database e, in caso di autenticazione fallita, proseguire il controllo su Gmail.&lt;/p&gt;
&lt;h3&gt;Implementazione &lt;span class="caps"&gt;CAS&lt;/span&gt; in Ruby&lt;/h3&gt;
&lt;p&gt;Esistono implementazioni in Ruby sia del &lt;a href="http://code.google.com/p/rubycas-server/"&gt;server&lt;/a&gt; che del &lt;a href="http://rubyforge.org/projects/rubycas-client/"&gt;client&lt;/a&gt;. Entrambi sono installabili come gemme e permettono di &lt;a href="http://code.google.com/p/rubycas-server/wiki/QuickStart"&gt;costruire&lt;/a&gt; e &lt;a href="http://code.google.com/p/rubycas-server/wiki/HowToConfigure"&gt;configurare&lt;/a&gt; l’intera infrastruttura. Il server viene fornito con gli &lt;em&gt;authenticator&lt;/em&gt; più comuni (&lt;span class="caps"&gt;SQL&lt;/span&gt;, &lt;span class="caps"&gt;LDAP&lt;/span&gt;, ActiveDirectory, Google) che possono essere modificati con poche righe di codice. E’ molto semplice personalizzare anche l’aspetto grafico della pagina di login del server, così da adattarla al &lt;em&gt;look and feel&lt;/em&gt; delle applicazioni che ne condividono il servizio.&lt;/p&gt;</description><link>http://blog.ateapick.com/post/1166279196</link><guid>http://blog.ateapick.com/post/1166279196</guid><pubDate>Fri, 30 Jan 2009 20:09:00 +0100</pubDate><category>ldap,</category><category>active directory</category><category>login</category><category>rails</category><category>ruby</category><category>ruby</category><dc:creator>dando76</dc:creator></item><item><title>Posizionamento assoluto e relativo con IE6</title><description>&lt;p&gt;Attraverso la proprietà &lt;span class="codex"&gt;position:&lt;/span&gt; è possibile controllare in maniera piuttosto precisa il posizionamento all’interno di una pagina web di un elemento di tipo &lt;strong&gt;block-level&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;In particolare il posizionamento relativo – &lt;span class="codex"&gt;position: relative&lt;/span&gt; – usato in combinazione con una o più proprietà di offset (&lt;span class="codex"&gt;top:&lt;/span&gt;, &lt;span class="codex"&gt;right:&lt;/span&gt;, &lt;span class="codex"&gt;bottom:&lt;/span&gt;, &lt;span class="codex"&gt;left:&lt;/span&gt;) consente di definire lo scostamento dell’elemento rispetto alla posizione originale assunta dall’elemento stesso all’interno del normale flusso di rendering della pagina. Utilizzato ad esempio in combinazione con le proprietà &lt;span class="codex"&gt;top: 10px&lt;/span&gt; e &lt;span class="codex"&gt;left: 10px&lt;/span&gt;, l’elemento verrà disegnato spostato di 10px in alto e a sinistra rispetto alla posizione nella quale si sarebbe dovuto trovare.&lt;/p&gt;
&lt;p&gt;Il posizionamento assoluto – &lt;span class="codex"&gt;position: absolute&lt;/span&gt; – consente invece di collocare esattamente un elemento in un qualsiasi punto della pagina, indipendentemente dalla presenza degli altri elementi. Utilizzato ad esempio in combinazione con le proprietà &lt;span class="codex"&gt;top: 0px&lt;/span&gt; e &lt;span class="codex"&gt;left: 0px&lt;/span&gt;, l’elemento verrà disegnato nell’angolo superiore sinistro della pagina.&lt;/p&gt;
&lt;p&gt;È importante tener conto che un elemento posizionato in modo assoluto “esce” dal normale flusso e gli altri elementi della pagina si comportano come se l’elemento stesso &lt;strong&gt;non esistesse&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;Posizionamento assoluto all’interno di un posizionamento relativo&lt;/h3&gt;
&lt;p&gt;Ciò che si rivela estremamente utile nella realizzazione di template &lt;span class="caps"&gt;HTML&lt;/span&gt; di una certà complessità è l’utilizzo combinato delle due proprietà, in particolare inserendo un elemento posizionato in maniera assoluta all’interno di un altro posizionato in maniera relativa:&lt;/p&gt;
&lt;pre&gt; 
&lt;code&gt; 
    &amp;lt;div style="position: relative"&amp;gt;
        &amp;lt;div style="position: absolute"&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&lt;/code&gt; 
&lt;/pre&gt;
&lt;p&gt;Così facendo si re-inizializzano le coordinate 0,0 dell’elemento &lt;em&gt;absolute&lt;/em&gt; rispetto all’angolo superiore sinistro dell’elemento padre, invece che rispetto all’intera pagina. Quindi dando le proprietà &lt;span class="codex"&gt;top: 0px&lt;/span&gt; e &lt;span class="codex"&gt;left: 0px&lt;/span&gt; l’elemento &lt;em&gt;absolute&lt;/em&gt; verrà disegnato nell’angolo superiore sinistro dell’elemento &lt;em&gt;relative&lt;/em&gt; che lo contiene.&lt;/p&gt;
&lt;h3&gt;Internet Explorer 6&lt;/h3&gt;
&lt;p&gt;Inutile sottolineare come IE6 interpreti in modo del tutto arbitrario questa impaginazione e necessiti di un apposito &lt;em&gt;workaround&lt;/em&gt;. Per tutti coloro che pensano che IE6 sia ormai storia, l’ultimo rilevazione di &lt;a href="http://marketshare.hitslink.com/"&gt;Market Share&lt;/a&gt; del Dicembre 2008 lo posiziona al secondo posto tra i browser dopo il fratello maggiore IE7 e subito prima di Firefox 3, con ancora il 20% di quota di installato.&lt;/p&gt;
&lt;p&gt;Il problema principale dell’utilizzo di questa tecnica risiede nel fatto che IE6 non sempre inizia a calcolare le coordinate dell’elemento posizionato in maniera assoluta dal nuovo “0,0” originato dall’elemento contenitore. Lo fa solo &lt;em&gt;a volte&lt;/em&gt;!&lt;/p&gt;
&lt;p&gt;IE6 infatti contiene una proprietà &lt;em&gt;nascosta&lt;/em&gt; chiamata &lt;strong&gt;“hasLayout”&lt;/strong&gt; sulla quale non è possibile intervenire attraverso i fogli di stile. É una variabile nascosta che che il “browser dei miracoli” utilizza per tenere traccia di ogni elemento della pagina. Trovate maggiori informazioni &lt;a href="http://www.satzansatz.de/cssd/onhavinglayout.html"&gt;qui&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Per risolvere il nostro problema invece è possibile &lt;strong&gt;dare&lt;/strong&gt; al nostro elemento un &lt;strong&gt;layout&lt;/strong&gt; assegnandogli degli attributi come larghezza, altezza, floating o altro ancora. Spesso però, come sarà sicuramente capitato a molti, è impossibile assegnare detti attributi agli elementi senza inficiare il corretto layout della pagina.&lt;/p&gt;
&lt;p&gt;Fortunatamente ci viene incontro un fix specifico per IE6:&lt;/p&gt;
&lt;pre&gt; 
&lt;code&gt; 
    &amp;lt;!--[if IE]&amp;gt;&amp;lt;style&amp;gt;
    .ie_layout {
      height: 0;
      he\ight: auto;
      zoom: 1;
    }
    &amp;lt;/style&amp;gt;&amp;lt;![endif]--&amp;gt;
&lt;/code&gt; 
&lt;/pre&gt;
&lt;p&gt;É sufficiente definire nel foglio di stile la classe &lt;span class="codex"&gt;.ie_layout&lt;/span&gt; secondo la sintassi sopra riportata e assegnarla all’elemento padre, ovvero quello posizionato in maniera &lt;strong&gt;assoluta&lt;/strong&gt;. Il commento condizionale [if IE] è un comando proprietario di Internet Explorer che fa si che questa classe e questi attributi siano interpretati solo da quest’ultimo.&lt;/p&gt;
&lt;p&gt;Come personale linea di sviluppo, cerco sempre di non utilizzare  i filtri nei &lt;span class="caps"&gt;CSS&lt;/span&gt; per evitare di introdurre istruzioni non richieste e di &lt;em&gt;sporcare&lt;/em&gt; il codice. Preferisco piuttosto utilizzare più codice &lt;span class="caps"&gt;HTML&lt;/span&gt; distribuendo gli attributi su vari elementi indentati (ad esempio per ovviare al noto problema del &lt;a href="http://en.wikipedia.org/wiki/Internet_Explorer_box_model_bug"&gt;Box Model di IE&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Tuttavia in alcuni casi limite come questo, sono l’unica risorsa per riuscire ad ovviare a tutti quei problemi introdotti da alcuni browser ed in modo particolare dal mai troppo denigrato Internet Explorer 6.&lt;/p&gt;</description><link>http://blog.ateapick.com/post/814713117</link><guid>http://blog.ateapick.com/post/814713117</guid><pubDate>Fri, 09 Jan 2009 09:22:00 +0100</pubDate><category>ie6</category><category>css</category><category>html</category><dc:creator>dando76</dc:creator></item><item><title>Sviluppare applicazioni Facebook con Ruby on Rails</title><description>&lt;p&gt;&lt;a href="http://www.facebook.com"&gt;Facebook&lt;/a&gt; non ha certo bisogno di presentazioni, soprattutto dopo il successo esponenziale che, da qualche mese a questa parte, ha vissuto anche in Italia.&lt;/p&gt;
&lt;p&gt;Come in tutte le storie di successo c‘è chi utilizza morbosamente e chi critica cinicamente l’applicazione del momento; tuttavia nessuno può negare come il fenomeno debba essere degno di considerazione, non solo da un punto di vista sociale ma anche per il potenziale offerto dal bacino di utenti (attualmente più di 170.000.000) che raccoglie.&lt;/p&gt;
&lt;p&gt;In qualità di sviluppatore apprezzo molto la presenza di &lt;a href="http://developers.facebook.com/"&gt;&lt;span class="caps"&gt;REST&lt;/span&gt; &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/a&gt; che consentono la realizzazione di applicazioni sulla piattaforma Facebook; una scelta che, a mio avviso, conferma la regola per cui le politiche di “apertura informatica” siano assolutamente vincenti, come già ampiamente dimostrato da realtà del calibro di Google (Maps, Calendar, Youtube etc.), &lt;a href="http://www.37signals.com/"&gt;37Signals&lt;/a&gt; e da tutti i loro “discepoli”.&lt;/p&gt;
&lt;p&gt;Per iniziare a scrivere applicazioni Facebook con Rails, segnalo 2 risorse interessanti, entrambe firmate “Mike Mangino”, uno dei maggiori esperti al mondo sull’argomento, reperibili da &lt;a href="http://www.pragprog.com"&gt;The Pragmatic Bookshelf&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.pragprog.com/titles/mmfacer/developing-facebook-platform-applications-with-rails"&gt;Developing Facebook Platform Applications with Rails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.pragprog.com/screencasts/v-mmfacer/rails-development-for-the-facebook-platform"&gt;Rails Development for the Facebook Platform&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Il primo è un libro, il secondo uno screencast suddiviso in due parti che tratta anche l’utilizzo dei plugin &lt;a href="http://facebooker.rubyforge.org/"&gt;facebooker&lt;/a&gt; (un wrapper ruby sulle &lt;span class="caps"&gt;REST&lt;/span&gt; &lt;span class="caps"&gt;API&lt;/span&gt; di Facebook) e &lt;a href="http://github.com/mmangino/facebooker_authentication/tree/master"&gt;facebooker_authentication&lt;/a&gt; (per l’autenticazione di utenti Facebook).&lt;/p&gt;
&lt;p&gt;Considerato che anche la visionaria Apple annovera l’integrazione di Facebook tra le novità dei &lt;a href="http://www.apple.com/it/ilife/iphoto/"&gt;iPhoto ’09&lt;/a&gt;, può essere che valga la pena approfondire l’argomento.&lt;/p&gt;</description><link>http://blog.ateapick.com/post/1166290093</link><guid>http://blog.ateapick.com/post/1166290093</guid><pubDate>Thu, 08 Jan 2009 00:00:00 +0100</pubDate><category>api</category><category>facebook</category><category>rails</category><category>rest</category><category>ruby</category><category>ruby</category><dc:creator>dando76</dc:creator></item><item><title>PDF::Writer vs RGhost per la creazione di pdf in ruby</title><description>&lt;p&gt;Esistono molti scenari nei quali si rende necessaria la creazione di documenti pdf a partire, ad esempio, dai dati presenti in un datatabse.&lt;/p&gt;
&lt;p&gt;Ruby offre varie soluzioni che possano essere di ausilio alla risoluzione di questo tipo di problema. Una di queste è la gemma &lt;a href="http://ruby-pdf.rubyforge.org/pdf-writer/"&gt;&lt;span class="caps"&gt;PDF&lt;/span&gt;::Writer&lt;/a&gt;, che consente la creazione di &lt;span class="caps"&gt;PDF&lt;/span&gt; attareverso l’utilizzo di librerie native. Potete trovare una buona &lt;a href="http://www.extendi.it/ruby-on-rails/index.php/2006/10/23/pdf-writer-per-creare-pdf-in-rails/"&gt;guida introduttiva&lt;/a&gt; in italiano all’interno del blog dei nostri amici di &lt;a href="http://www.extendi.it"&gt;extendi&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Recentemente ho sperimentato un approccio alternativo a pdf-writer utilizzando &lt;a href="http://rubyforge.org/projects/rghost/"&gt;Rghost&lt;/a&gt;, una gemma che utilizza il framework &lt;a href="http://pages.cs.wisc.edu/~ghost/"&gt;Ghostscript&lt;/a&gt; per la conversione tra formati (&lt;span class="caps"&gt;PDF&lt;/span&gt;,PS,GIF,TIF,PNG,JPG,etc) e permette l’utilizzo di template &lt;span class="caps"&gt;EPS&lt;/span&gt; nella creazione dei documenti.&lt;/p&gt;
&lt;p&gt;Sulla &lt;a href="http://rubyforge.org/docman/?group_id=3796"&gt;documentazione ufficiale&lt;/a&gt; è disponibile un manuale molto ben fatto. Grazie alla sua sintassi più &lt;em&gt;ruby-like&lt;/em&gt; e, soprattutto, alla possibilità di utilizzare dei template (&lt;span class="caps"&gt;EPS&lt;/span&gt;) nella creazione dei documenti, rghost sta decisamente guadagnando un posto privilegiato tra i miei “attrezzi del mestiere”, fermo restando che ritengo siano entrambi ottimi progetti.&lt;/p&gt;</description><link>http://blog.ateapick.com/post/1166296194</link><guid>http://blog.ateapick.com/post/1166296194</guid><pubDate>Tue, 18 Nov 2008 00:00:00 +0100</pubDate><category>gem</category><category>pdf</category><category>ruby</category><category>template</category><dc:creator>dando76</dc:creator></item><item><title>Ruby on Rails Menù</title><description>&lt;p&gt;In molte interfacce viene utilizzato un menù in cui, durante la navigazione, la voce selezionata assume uno stile diverso dalle altre, attraverso l’assegnazione di una classe (es. “selected”) sulla base della pagina corrente.&lt;/p&gt;
&lt;p&gt;Questo tipo di effetto può essere ottenuto in vari modi, ad esempio assegnando la classe “selected” in base ai valori assunti dal &lt;em&gt;current_controller&lt;/em&gt; e dalla &lt;em&gt;current_action&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Personalmente preferisco un approccio più semplice, pragmatico e flessibile.&lt;/p&gt;
&lt;p&gt;Scriviamo un helper di questo tipo:&lt;/p&gt;

&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="source source_ruby"&gt;&lt;span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;menu_item&lt;/span&gt; &lt;span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby"&gt;(&lt;/span&gt;&lt;span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby"&gt;key&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; path&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; type&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby"&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 2&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;if&lt;/span&gt; instance_variable_get&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;@current_&lt;span class="source source_ruby source_ruby_embedded source_ruby_embedded_source"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;#{&lt;/span&gt;type&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;}&lt;/span&gt;&lt;/span&gt;_item&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby"&gt;==&lt;/span&gt; key
&lt;span class="linenum"&gt; 3&lt;/span&gt; link_to content_tag&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;span&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; key&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;to_s&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; path&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;class&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;selected&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 4&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;else&lt;/span&gt;
&lt;span class="linenum"&gt; 5&lt;/span&gt; link_to content_tag&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;span&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; key&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;to_s&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; path 
&lt;span class="linenum"&gt; 6&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;
&lt;span class="linenum"&gt; 7&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Utilizzando l’helper possiamo scrivere un menù nel modo seguente:&lt;/p&gt;

&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="text text_html text_html_ruby"&gt;&lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;ul&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 2&lt;/span&gt; &lt;span class="meta meta_tag meta_tag_inline meta_tag_inline_any meta_tag_inline_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_inline entity_name_tag_inline_any entity_name_tag_inline_any_html"&gt;li&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%=&lt;/span&gt;menu_item &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;home&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; home_path&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;first_level&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_tag meta_tag_inline meta_tag_inline_any meta_tag_inline_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_inline entity_name_tag_inline_any entity_name_tag_inline_any_html"&gt;li&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 3&lt;/span&gt; &lt;span class="meta meta_tag meta_tag_inline meta_tag_inline_any meta_tag_inline_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_inline entity_name_tag_inline_any entity_name_tag_inline_any_html"&gt;li&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%=&lt;/span&gt;menu_item &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;about&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; about_path&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;first_level&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_tag meta_tag_inline meta_tag_inline_any meta_tag_inline_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_inline entity_name_tag_inline_any entity_name_tag_inline_any_html"&gt;li&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 4&lt;/span&gt; &lt;span class="meta meta_tag meta_tag_inline meta_tag_inline_any meta_tag_inline_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_inline entity_name_tag_inline_any entity_name_tag_inline_any_html"&gt;li&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%=&lt;/span&gt;menu_item &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;projects&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; projects_path&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;first_level&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_tag meta_tag_inline meta_tag_inline_any meta_tag_inline_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_inline entity_name_tag_inline_any entity_name_tag_inline_any_html"&gt;li&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 5&lt;/span&gt; &lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;ul&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;A questo punto basterà impostare (ad esempio attraverso un &lt;em&gt;before_filter&lt;/em&gt;) la variabile &lt;em&gt;@current_first_level_item&lt;/em&gt; con un valore tra :home, :about o :projects nei controller per selezionare la voce corrente. Scegliendo valori diversi del paramentro &lt;em&gt;type&lt;/em&gt; il controllo verrà fatto su variabili diverse e sarà quindi molto semplice far convivere con lo stesso sistema menù diversi, ad esempio un menù di primo livello ed uno di secondo livello.&lt;/p&gt;
&lt;p&gt;La flessibilità deriva dal fatto che in ogni &lt;em&gt;action&lt;/em&gt; siamo “liberi” di selezionare le giuste voci di ogni menù, svincolandoci da sistemi più rigidi basati sull’url.&lt;/p&gt;</description><link>http://blog.ateapick.com/post/1166299581</link><guid>http://blog.ateapick.com/post/1166299581</guid><pubDate>Mon, 03 Nov 2008 00:00:00 +0100</pubDate><category>menù</category><category>rails</category><category>ruby</category><category>webapp</category><dc:creator>dando76</dc:creator></item><item><title>Macchine a stati finiti (FSM) e il plugin acts_as_state_machine</title><description>&lt;p&gt;Una &lt;a href="http://it.wikipedia.org/wiki/Automa_a_stati_finiti"&gt;macchina a stati finiti&lt;/a&gt; (&lt;span class="caps"&gt;FSM&lt;/span&gt;) è un sistema dinamico costituito da un &lt;strong&gt;insieme finito di stati&lt;/strong&gt; e da una &lt;strong&gt;funzione di trasferimento&lt;/strong&gt; che ne specifica il comportamento, ovvero definisce le regole che determinano i passaggi della macchina da uno stato all’altro.&lt;/p&gt;
&lt;p&gt;La macchina può essere rappresentata tramite un &lt;a href="http://it.wikipedia.org/wiki/Teoria_dei_grafi"&gt;grafo diretto&lt;/a&gt; i cui nodi rappresentano gli stati e gli archi rappresentano le transizioni di stato delle macchina.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l953uoU2V41qcqixx.jpg"/&gt;&lt;/p&gt;
&lt;p&gt;Sono molteplici i problemi che possono essere modellati con una &lt;span class="caps"&gt;FSM&lt;/span&gt; e non poteva certo mancare un plugin Rails che ne rendesse &lt;em&gt;agile&lt;/em&gt; la codifica: si tratta di &lt;a href="http://agilewebdevelopment.com/plugins/acts_as_state_machine"&gt;acts_as_state_machine&lt;/a&gt;, una manciata di righe di codice sicuramente migliorabili ma che tutto sommato assolvono bene al loro compito. Una volta installato il plugin, occorrerà soltanto aggiungere un campo &lt;em&gt;state&lt;/em&gt; di tipo &lt;em&gt;string&lt;/em&gt; all’oggetto cui vogliamo assegnare le caratteristiche di &lt;span class="caps"&gt;FSM&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Facciamo un semplice esempio: vogliamo creare un’applicazione web accessibile attraverso &lt;strong&gt;iscrizioni a pagamento&lt;/strong&gt;. Dopo la registrazione, l’iscrizione sarà attiva e, ogni volta che riceveremo un pagamento, dovrà essere generata la fattura commerciale per il cliente. In caso di mancato pagamento l’iscrizione verrà sospesa mentre, se il cliente deciderà di cancellare la sua registrazione, l’iscrizione verrà eliminata. Ad ogni passaggio di stato dovrà essere inviata una notifica e-mail al cliente.&lt;/p&gt;
&lt;p&gt;La prima cosa da fare è modellare gli stati e gli eventi che determinano le transizioni di stato: niente di meglio che usare la vecchia accoppiata carta/penna, creando un diagramma simile a quello della figura precedente.&lt;/p&gt;
&lt;p&gt;Utilzzando il plugin risulta estremamente semplice tradurre il diagramma nel seguente modello Rails:&lt;/p&gt;

&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="source source_ruby"&gt;&lt;span class="meta meta_class meta_class_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_class keyword_control_class_ruby"&gt;class&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby"&gt;Subscription&lt;span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby"&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_inheritance punctuation_separator_inheritance_ruby"&gt;&amp;lt;&lt;/span&gt; ActiveRecord::Base&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 2&lt;/span&gt; 
&lt;span class="linenum"&gt; 3&lt;/span&gt; acts_as_state_machine &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;initial&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;active&lt;/span&gt;
&lt;span class="linenum"&gt; 4&lt;/span&gt; 
&lt;span class="linenum"&gt; 5&lt;/span&gt; state &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;active&lt;/span&gt;
&lt;span class="linenum"&gt; 6&lt;/span&gt; state &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;suspended&lt;/span&gt;
&lt;span class="linenum"&gt; 7&lt;/span&gt; 
&lt;span class="linenum"&gt; 8&lt;/span&gt; event &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;payment&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do
&lt;/span&gt;&lt;span class="linenum"&gt; 9&lt;/span&gt; 
&lt;span class="linenum"&gt; 10&lt;/span&gt; transitions &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;from&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;active&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt;
&lt;span class="linenum"&gt; 11&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;to&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;active&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt;
&lt;span class="linenum"&gt; 12&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;guard&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;get_payment&lt;/span&gt;
&lt;span class="linenum"&gt; 13&lt;/span&gt; 
&lt;span class="linenum"&gt; 14&lt;/span&gt; transitions &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;from&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;suspended&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt;
&lt;span class="linenum"&gt; 15&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;to&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;active&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt;
&lt;span class="linenum"&gt; 16&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;guard&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;notify_reactivation&lt;/span&gt;
&lt;span class="linenum"&gt; 17&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;
&lt;span class="linenum"&gt; 18&lt;/span&gt; 
&lt;span class="linenum"&gt; 19&lt;/span&gt; event &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;payment_failure&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do
&lt;/span&gt;&lt;span class="linenum"&gt; 20&lt;/span&gt; 
&lt;span class="linenum"&gt; 21&lt;/span&gt; transitions &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;from&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;active&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt;
&lt;span class="linenum"&gt; 22&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;to&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;suspended&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt;
&lt;span class="linenum"&gt; 23&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;guard&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;notify_suspension&lt;/span&gt;
&lt;span class="linenum"&gt; 24&lt;/span&gt; 
&lt;span class="linenum"&gt; 25&lt;/span&gt; transitions &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;from&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;suspended&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt;
&lt;span class="linenum"&gt; 26&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;to&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;suspended&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt;
&lt;span class="linenum"&gt; 27&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;guard&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;notify_new_payment_failure&lt;/span&gt; 
&lt;span class="linenum"&gt; 28&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;
&lt;span class="linenum"&gt; 29&lt;/span&gt; 
&lt;span class="linenum"&gt; 30&lt;/span&gt; &lt;span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby"&gt;private&lt;/span&gt;
&lt;span class="linenum"&gt; 31&lt;/span&gt; &lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;get_payment&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 32&lt;/span&gt; &lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt; &lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby"&gt;#&lt;/span&gt; make payment invoice
&lt;/span&gt;&lt;span class="linenum"&gt; 33&lt;/span&gt; &lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt; &lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby"&gt;#&lt;/span&gt; send payment email
&lt;/span&gt;&lt;span class="linenum"&gt; 34&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;
&lt;span class="linenum"&gt; 35&lt;/span&gt; 
&lt;span class="linenum"&gt; 36&lt;/span&gt; &lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;notify_reactivation&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 37&lt;/span&gt; &lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt; &lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby"&gt;#&lt;/span&gt; send reactivation email 
&lt;/span&gt;&lt;span class="linenum"&gt; 38&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;
&lt;span class="linenum"&gt; 39&lt;/span&gt; 
&lt;span class="linenum"&gt; 40&lt;/span&gt; &lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;notify_suspension&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 41&lt;/span&gt; &lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt; &lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby"&gt;#&lt;/span&gt; send suspension email
&lt;/span&gt;&lt;span class="linenum"&gt; 42&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;
&lt;span class="linenum"&gt; 43&lt;/span&gt; 
&lt;span class="linenum"&gt; 44&lt;/span&gt; &lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;notify_new_payment_failure&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 45&lt;/span&gt; &lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt; &lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby"&gt;#&lt;/span&gt; send alert for new payment failure
&lt;/span&gt;&lt;span class="linenum"&gt; 46&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;
&lt;span class="linenum"&gt; 47&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Nell’esempio, gli eventi possono essere chiamati attraverso i metodi:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;em&gt;@subscription.payment!&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;@subscription.payment_failure!&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Gli eventi &lt;em&gt;signup&lt;/em&gt; e &lt;em&gt;cancel&lt;/em&gt; del diagramma coincidono invece con l’effettiva creazione e distruzione della &lt;em&gt;subscription&lt;/em&gt; e non con delle transizioni di stato.&lt;/p&gt;
&lt;p&gt;Il modello è molto semplificato rispetto ad un caso reale, dove dovrebbero essere tenuti in considerazione altri stati ed eventi come la &lt;strong&gt;modifica dell’iscrizione&lt;/strong&gt; o la sospensione definitiva in seguito ad un &lt;strong&gt;numero massimo di pagamenti falliti&lt;/strong&gt;. Quello che conta è l’approccio con cui viene affrontato il problema e la “robustezza” della soluzione che ne scaturisce: un sistema ben modellato è un’ottima base per la scrittura di codice elegante e flessibile e le macchine a stati sono, a mio avviso, uno degli esempi più calzanti di come una buona progettazione porti vantaggi concreti, attribuendo un significato tangibile a quanto raccomandato in tutti i migliori testi di programmazione.&lt;/p&gt;</description><link>http://blog.ateapick.com/post/1166306485</link><guid>http://blog.ateapick.com/post/1166306485</guid><pubDate>Tue, 21 Oct 2008 00:00:00 +0200</pubDate><category>fsm</category><category>plugin</category><category>rails</category><category>ruby</category><dc:creator>dando76</dc:creator></item><item><title>HATBM Checkboxes</title><description>&lt;p&gt;Un problema molto semplice e ampiamente documentato è l’aggiornamento tramite checkbox delle associazioni tra due &lt;em&gt;model&lt;/em&gt; che sono in &lt;em&gt;relazione n:m&lt;/em&gt; tra loro:&lt;/p&gt;
&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails"&gt;&lt;span class="meta meta_rails meta_rails_model"&gt;&lt;span class="meta meta_class meta_class_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_class keyword_control_class_ruby"&gt;class&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby"&gt;Conference&lt;span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby"&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_inheritance punctuation_separator_inheritance_ruby"&gt;&amp;lt;&lt;/span&gt; ActiveRecord::Base&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 2&lt;/span&gt; &lt;span class="support support_function support_function_activerecord support_function_activerecord_rails"&gt;has_and_belongs_to_many&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;speakers&lt;/span&gt;
&lt;/span&gt;&lt;span class="linenum"&gt; 3&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails"&gt;&lt;span class="meta meta_rails meta_rails_model"&gt;&lt;span class="meta meta_class meta_class_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_class keyword_control_class_ruby"&gt;class&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby"&gt;Speaker&lt;span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby"&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_inheritance punctuation_separator_inheritance_ruby"&gt;&amp;lt;&lt;/span&gt; ActiveRecord::Base&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 2&lt;/span&gt; &lt;span class="support support_function support_function_activerecord support_function_activerecord_rails"&gt;has_and_belongs_to_many&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;conferences&lt;/span&gt;
&lt;/span&gt;&lt;span class="linenum"&gt; 3&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Per selezionare gli &lt;em&gt;speaker&lt;/em&gt; nella form di una &lt;em&gt;conference&lt;/em&gt;, tramite l’utilizzo di checkbox, basta scrivere:&lt;/p&gt;
&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="text text_html text_html_ruby"&gt;&lt;span class="comment comment_block comment_block_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_html"&gt;&amp;lt;!--&lt;/span&gt; conferences/_form.rhtml &lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_html"&gt;--&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 2&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;Speaker&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;all&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;each &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do &lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt;&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;speaker&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 3&lt;/span&gt; &lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;div&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 4&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%=&lt;/span&gt; check_box_tag &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;conference[speaker_ids][]&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; speaker&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;id&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; &lt;span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby"&gt;@&lt;/span&gt;conference&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;speakers&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;include?&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;speaker&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 5&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%=&lt;/span&gt; speaker&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;name &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 6&lt;/span&gt; &lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;div&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 7&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;e modificare l’&lt;em&gt;update action&lt;/em&gt; in modo che l’aggiornamento delle associazioni funzioni correttamente anche nel caso in cui nessuna checkbox sia selezionata:&lt;/p&gt;
&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails"&gt;&lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby"&gt;#&lt;/span&gt; conferences_controller.rb
&lt;/span&gt;&lt;span class="linenum"&gt; 2&lt;/span&gt; &lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;update&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 3&lt;/span&gt; params&lt;span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby"&gt;[&lt;/span&gt;&lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;conference&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby"&gt;][&lt;/span&gt;&lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;speaker_ids&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby"&gt;]&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby"&gt;||=&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby"&gt;[]&lt;/span&gt;
&lt;span class="linenum"&gt; 4&lt;/span&gt; &lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt; &lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby"&gt;#&lt;/span&gt;...
&lt;/span&gt;&lt;span class="linenum"&gt; 5&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;</description><link>http://blog.ateapick.com/post/1166330044</link><guid>http://blog.ateapick.com/post/1166330044</guid><pubDate>Wed, 08 Oct 2008 00:00:00 +0200</pubDate><category>associazioni</category><category>checkbox</category><category>form</category><category>rails</category><category>ruby</category><dc:creator>dando76</dc:creator></item><item><title>Parametrizzare un'applicazione Rails</title><description>&lt;p&gt;In molte applicazioni può essere opportuno utilizzare delle costanti con cui parametrizzare alcune funzionalità, eventualmente in base all’&lt;em&gt;environment&lt;/em&gt; corrente.&lt;/p&gt;
&lt;p&gt;Un esempio calzante è la gestione dei parametri di connessione al database che, in un applicazione Rails, vengono scritti in &lt;em&gt;/config/database.yml&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Seguendo lo stesso approccio, è molto semplice impostare parametri personalizzati. Creiamo il file &lt;em&gt;/config/application.yml&lt;/em&gt; e scriviamo i nostri parametri con una struttura del tipo:&lt;/p&gt;

&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="source source_yaml"&gt;&lt;span class="meta meta_tag meta_tag_yaml"&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_yaml"&gt;development&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_key-value punctuation_separator_key-value_yaml"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;span class="linenum"&gt; 2&lt;/span&gt; &lt;span class="string string_unquoted string_unquoted_yaml"&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_yaml"&gt;key1&lt;span class="punctuation punctuation_separator punctuation_separator_key-value punctuation_separator_key-value_yaml"&gt;:&lt;/span&gt;&lt;/span&gt; &lt;span class="string string_unquoted string_unquoted_yaml"&gt;value1&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 3&lt;/span&gt; &lt;span class="string string_unquoted string_unquoted_yaml"&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_yaml"&gt;key2&lt;span class="punctuation punctuation_separator punctuation_separator_key-value punctuation_separator_key-value_yaml"&gt;:&lt;/span&gt;&lt;/span&gt; &lt;span class="string string_unquoted string_unquoted_yaml"&gt;value2&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 4&lt;/span&gt; &lt;span class="string string_unquoted string_unquoted_yaml"&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_yaml"&gt;key3&lt;span class="punctuation punctuation_separator punctuation_separator_key-value punctuation_separator_key-value_yaml"&gt;:&lt;/span&gt;&lt;/span&gt; &lt;span class="string string_unquoted string_unquoted_yaml"&gt;value3 &lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 5&lt;/span&gt; 
&lt;span class="linenum"&gt; 6&lt;/span&gt; &lt;span class="meta meta_tag meta_tag_yaml"&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_yaml"&gt;test&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_key-value punctuation_separator_key-value_yaml"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;span class="linenum"&gt; 7&lt;/span&gt; &lt;span class="string string_unquoted string_unquoted_yaml"&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_yaml"&gt;key1&lt;span class="punctuation punctuation_separator punctuation_separator_key-value punctuation_separator_key-value_yaml"&gt;:&lt;/span&gt;&lt;/span&gt; &lt;span class="string string_unquoted string_unquoted_yaml"&gt;value1&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 8&lt;/span&gt; &lt;span class="string string_unquoted string_unquoted_yaml"&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_yaml"&gt;key2&lt;span class="punctuation punctuation_separator punctuation_separator_key-value punctuation_separator_key-value_yaml"&gt;:&lt;/span&gt;&lt;/span&gt; &lt;span class="string string_unquoted string_unquoted_yaml"&gt;value2&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 9&lt;/span&gt; &lt;span class="string string_unquoted string_unquoted_yaml"&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_yaml"&gt;key3&lt;span class="punctuation punctuation_separator punctuation_separator_key-value punctuation_separator_key-value_yaml"&gt;:&lt;/span&gt;&lt;/span&gt; &lt;span class="string string_unquoted string_unquoted_yaml"&gt;value3 &lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 10&lt;/span&gt; 
&lt;span class="linenum"&gt; 11&lt;/span&gt; &lt;span class="meta meta_tag meta_tag_yaml"&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_yaml"&gt;production&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_key-value punctuation_separator_key-value_yaml"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;span class="linenum"&gt; 12&lt;/span&gt; &lt;span class="string string_unquoted string_unquoted_yaml"&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_yaml"&gt;key1&lt;span class="punctuation punctuation_separator punctuation_separator_key-value punctuation_separator_key-value_yaml"&gt;:&lt;/span&gt;&lt;/span&gt; &lt;span class="string string_unquoted string_unquoted_yaml"&gt;value1&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 13&lt;/span&gt; &lt;span class="string string_unquoted string_unquoted_yaml"&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_yaml"&gt;key2&lt;span class="punctuation punctuation_separator punctuation_separator_key-value punctuation_separator_key-value_yaml"&gt;:&lt;/span&gt;&lt;/span&gt; &lt;span class="string string_unquoted string_unquoted_yaml"&gt;value2&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 14&lt;/span&gt; &lt;span class="string string_unquoted string_unquoted_yaml"&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_yaml"&gt;key3&lt;span class="punctuation punctuation_separator punctuation_separator_key-value punctuation_separator_key-value_yaml"&gt;:&lt;/span&gt;&lt;/span&gt; &lt;span class="string string_unquoted string_unquoted_yaml"&gt;value3 &lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Creiamo poi il file &lt;em&gt;/config/initializers/application.rb&lt;/em&gt;:&lt;/p&gt;

&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="source source_ruby"&gt;
&lt;span class="linenum"&gt; 2&lt;/span&gt; &lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;APPLICATION&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;YAML&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;load_file&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;&lt;span class="source source_ruby source_ruby_embedded source_ruby_embedded_source"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;#{&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;RAILS_ROOT&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;}&lt;/span&gt;&lt;/span&gt;/config/application.yml&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby"&gt;[&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;RAILS_ENV&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby"&gt;]&lt;/span&gt;
&lt;span class="linenum"&gt; 3&lt;/span&gt; 
&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;In questo modo avremo a disposizione dell’applicazione il seguente &lt;em&gt;hash&lt;/em&gt;:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;APPLICATION&lt;/span&gt; = {‘key1’ =&amp;gt; ‘value1’, ‘key2’ =&amp;gt; ‘value2’, ‘key3’ =&amp;gt; ‘value3’}&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;i cui valori saranno quelli che abbiamo impostato per l’ambiente corrente.&lt;/p&gt;</description><link>http://blog.ateapick.com/post/1166338537</link><guid>http://blog.ateapick.com/post/1166338537</guid><pubDate>Mon, 06 Oct 2008 00:00:00 +0200</pubDate><category>config</category><category>rails</category><category>yml</category><category>ruby</category><dc:creator>dando76</dc:creator></item><item><title>Popolare il database di sviluppo in un progetto Rails</title><description>&lt;p&gt;In un progetto Rails molto spesso è utile popolare il database di sviluppo con dati di test, in modo da simulare l’ambiente di produzione.&lt;/p&gt;
&lt;p&gt;Supponiamo di sviluppare un &lt;a href="http://it.wikipedia.org/wiki/Rete_sociale"&gt;Social Network&lt;/a&gt; che preveda l’iscrizione di utenti e la creazione di relazioni di conoscenza tra essi. Per testare le funzionalità del sistema potrebbe essere utile popolare il database in &lt;em&gt;development&lt;/em&gt; con un numero sufficientemente grande di iscrizioni e relazioni.&lt;/p&gt;
&lt;p&gt;Un’opzione potrebbe essere quella di armarsi di una buona dose di pazienza e fare data entry…bene…passiamo alla seconda opzione: scrivere uno script in ruby (o in qualsiasi altro linguaggio) che crei, con un po’ di fantasia, un buon numero di record sul database.&lt;/p&gt;
&lt;p&gt;Un’idea potrebbe essere quella di sfruttare un contatore di record per creare campi distinti:&lt;/p&gt;
&lt;p&gt;id             name             email             phone                               1             user_1             user_1@example.com             0001                               2             user_2             user_1@example.com             0002                               3             user_3             user_3@example.com             0003                               …             …             …             …                               1000             user_1000             user_1000@example.com             1000&lt;/p&gt;
&lt;p&gt;Ho seguito questo approccio finchè non ho provato le gemme &lt;a href="http://populator.rubyforge.org/"&gt;pupulator&lt;/a&gt; e &lt;a href="http://faker.rubyforge.org/"&gt;faker&lt;/a&gt;, attraverso le quali è molto semplice scrivere un &lt;em&gt;rake task&lt;/em&gt; come il seguente:&lt;/p&gt;

&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="source source_ruby"&gt;namespace &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;db&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do
&lt;/span&gt;&lt;span class="linenum"&gt; 2&lt;/span&gt; desc &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;Svuota e popola il database con dati di test&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 3&lt;/span&gt; task &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;populate&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;environment&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do
&lt;/span&gt;&lt;span class="linenum"&gt; 4&lt;/span&gt; &lt;span class="meta meta_require meta_require_ruby"&gt;&lt;span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby"&gt;require&lt;/span&gt; &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;populator&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 5&lt;/span&gt; &lt;span class="meta meta_require meta_require_ruby"&gt;&lt;span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby"&gt;require&lt;/span&gt; &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;faker&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 6&lt;/span&gt; 
&lt;span class="linenum"&gt; 7&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby"&gt;[&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;User&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; &lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;Link&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby"&gt;]&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;each&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby"&gt;&amp;amp;&lt;/span&gt;&lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;delete_all&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;
&lt;span class="linenum"&gt; 8&lt;/span&gt; 
&lt;span class="linenum"&gt; 9&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;User&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;populate &lt;span class="constant constant_numeric constant_numeric_ruby"&gt;1000&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do &lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt;&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;user&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt;
&lt;span class="linenum"&gt; 10&lt;/span&gt; user&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;name &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;Faker&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="support support_class support_class_ruby"&gt;Name&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;name
&lt;span class="linenum"&gt; 11&lt;/span&gt; user&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;email &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;Faker&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="support support_class support_class_ruby"&gt;Internet&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;email
&lt;span class="linenum"&gt; 12&lt;/span&gt; user&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;phone &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;Faker&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="support support_class support_class_ruby"&gt;PhoneNumber&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;phone_number
&lt;span class="linenum"&gt; 13&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;
&lt;span class="linenum"&gt; 14&lt;/span&gt; 
&lt;span class="linenum"&gt; 15&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;Link&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;populate &lt;span class="constant constant_numeric constant_numeric_ruby"&gt;10000&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do &lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt;&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;link&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt;
&lt;span class="linenum"&gt; 16&lt;/span&gt; link&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;user_id &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="constant constant_numeric constant_numeric_ruby"&gt;1&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;..&lt;/span&gt;&lt;span class="constant constant_numeric constant_numeric_ruby"&gt;1000&lt;/span&gt;
&lt;span class="linenum"&gt; 17&lt;/span&gt; link&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;friend_id &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="constant constant_numeric constant_numeric_ruby"&gt;1&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;..&lt;/span&gt;&lt;span class="constant constant_numeric constant_numeric_ruby"&gt;1000&lt;/span&gt;
&lt;span class="linenum"&gt; 18&lt;/span&gt; &lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt; &lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby"&gt;#&lt;/span&gt; trascuriamo per semplicità il controllo friend_id != user_id
&lt;/span&gt;&lt;span class="linenum"&gt; 19&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;
&lt;span class="linenum"&gt; 20&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Il comando &lt;em&gt;rake db:populate&lt;/em&gt; popola il database con 1000 utenti e 10000 relazioni casuali tra di essi. La documentazione delle due gemme mostra come sia molto comodo creare dati fittizzi e abbastanza…“realistici” ;)&lt;/p&gt;
&lt;p&gt;id             name             email             phone                               1             Jack Shephard             jack@lost.com             48&amp;#160;15162342                               2             Kate Austen             kate@lost.com             48&amp;#160;15162342                               3             John Locke             john@lost.com             48&amp;#160;15162342                               …             …             …             …                               1000             Mr. Eko             eko@lost.com             48&amp;#160;15162342&lt;/p&gt;</description><link>http://blog.ateapick.com/post/1166347664</link><guid>http://blog.ateapick.com/post/1166347664</guid><pubDate>Tue, 30 Sep 2008 00:00:00 +0200</pubDate><category>database</category><category>gems</category><category>rails</category><category>ruby</category><dc:creator>dando76</dc:creator></item><item><title>Ruby on Rails: oggetti multipli nella stessa form</title><description>&lt;p&gt;Supponiamo di avere 2 model &lt;em&gt;Author&lt;/em&gt; e &lt;em&gt;Book&lt;/em&gt; in &lt;strong&gt;relazione 1:n&lt;/strong&gt; tra loro: vogliamo scrivere una form per la creazione e la modifica di un &lt;em&gt;author&lt;/em&gt; e di uno o più &lt;em&gt;book&lt;/em&gt; associati. In particolare vogliamo avere la possibilità di aggiungere e rimuovere un numero qualsiasi di &lt;em&gt;book&lt;/em&gt; nella &lt;strong&gt;stessa form&lt;/strong&gt; di &lt;em&gt;author&lt;/em&gt;. Il risultato sarà qualcosa di questo tipo:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l954u1wPL51qcqixx.png"/&gt;&lt;/p&gt;
&lt;p&gt;Cominciamo con l’esprimere la relazione tra i due oggetti:&lt;/p&gt;
&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails"&gt;&lt;span class="meta meta_rails meta_rails_model"&gt;&lt;span class="meta meta_class meta_class_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_class keyword_control_class_ruby"&gt;class&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby"&gt;Author&lt;span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby"&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_inheritance punctuation_separator_inheritance_ruby"&gt;&amp;lt;&lt;/span&gt; ActiveRecord::Base&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; 
&lt;span class="linenum"&gt; 2&lt;/span&gt; &lt;span class="support support_function support_function_activerecord support_function_activerecord_rails"&gt;has_many&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;books&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;dependent&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;destroy&lt;/span&gt; 
&lt;/span&gt;&lt;span class="linenum"&gt; 3&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails"&gt;&lt;span class="meta meta_rails meta_rails_model"&gt;&lt;span class="meta meta_class meta_class_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_class keyword_control_class_ruby"&gt;class&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby"&gt;Book&lt;span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby"&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_inheritance punctuation_separator_inheritance_ruby"&gt;&amp;lt;&lt;/span&gt; ActiveRecord::Base&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; 
&lt;span class="linenum"&gt; 2&lt;/span&gt; &lt;span class="support support_function support_function_activerecord support_function_activerecord_rails"&gt;belongs_to&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;author&lt;/span&gt;
&lt;/span&gt;&lt;span class="linenum"&gt; 3&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Nella action &lt;em&gt;new&lt;/em&gt; di &lt;em&gt;/app/controllers/authors_controller.rb&lt;/em&gt; costruiamo un’istanza di un &lt;em&gt;author&lt;/em&gt; e di 3&amp;#160;&lt;em&gt;book&lt;/em&gt; associati nel seguente modo:&lt;/p&gt;
&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails"&gt;&lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;new&lt;/span&gt;&lt;/span&gt; 
&lt;span class="linenum"&gt; 2&lt;/span&gt; &lt;span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby"&gt;@&lt;/span&gt;author&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;Author&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;&lt;span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby"&gt;new&lt;/span&gt; 
&lt;span class="linenum"&gt; 3&lt;/span&gt; &lt;span class="constant constant_numeric constant_numeric_ruby"&gt;3&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;times &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do
&lt;/span&gt;&lt;span class="linenum"&gt; 4&lt;/span&gt; &lt;span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby"&gt;@&lt;/span&gt;author&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;books&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;build
&lt;span class="linenum"&gt; 5&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;
&lt;span class="linenum"&gt; 6&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;In &lt;em&gt;/app/views/authors/new.html.erb&lt;/em&gt; creiamo la form che contiene i campi dell’autore e dei libri associati (racchiusi nel parziale &lt;em&gt;/app/views/authors/_book.html.erb&lt;/em&gt;). Per semplicità consideriamo solo il campo &lt;em&gt;name&lt;/em&gt; per l’autore e il campo &lt;em&gt;title&lt;/em&gt; per i libri.&lt;/p&gt;
&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="text text_html text_html_ruby"&gt;&lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%&lt;/span&gt; form_for &lt;span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby"&gt;@&lt;/span&gt;author&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do &lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt;&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;f&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt; 
&lt;span class="linenum"&gt; 2&lt;/span&gt; &lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;p&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Name: &lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%=&lt;/span&gt; f&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;text_field &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;name&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;p&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; 
&lt;span class="linenum"&gt; 3&lt;/span&gt; &lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;div&lt;/span&gt; &lt;span class="meta meta_attribute-with-value meta_attribute-with-value_id meta_attribute-with-value_id_html"&gt;&lt;span class="entity entity_other entity_other_attribute-name entity_other_attribute-name_id entity_other_attribute-name_id_html"&gt;id&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_key-value punctuation_separator_key-value_html"&gt;=&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_html"&gt;"&lt;/span&gt;&lt;span class="meta meta_toc-list meta_toc-list_id meta_toc-list_id_html"&gt;books&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_html"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; 
&lt;span class="linenum"&gt; 4&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="support support_function support_function_actionpack support_function_actionpack_rails"&gt;render&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;partial&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;book&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;collection&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby"&gt;@&lt;/span&gt;author&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;books &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 5&lt;/span&gt; &lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;div&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; 
&lt;span class="linenum"&gt; 6&lt;/span&gt; &lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;p&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%=&lt;/span&gt; add_book_link &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;add book&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;p&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; 
&lt;span class="linenum"&gt; 7&lt;/span&gt; &lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;p&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%=&lt;/span&gt; f&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;submit &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;save&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;p&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; 
&lt;span class="linenum"&gt; 8&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Il codice per &lt;em&gt;add_book_link&lt;/em&gt; (riga 6) si trova in &lt;em&gt;/app/helpers/authors_helper.rb&lt;/em&gt; e genera un link Ajax che “appende” un nuovo libro alla form:&lt;/p&gt;
&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="source source_ruby"&gt;&lt;span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;add_book_link&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby"&gt;(&lt;/span&gt;&lt;span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby"&gt;name&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby"&gt;)&lt;/span&gt;&lt;/span&gt; 
&lt;span class="linenum"&gt; 2&lt;/span&gt; link_to_function name &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do &lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt;&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;page&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt; 
&lt;span class="linenum"&gt; 3&lt;/span&gt; page&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;insert_html &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;bottom&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;books&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;partial&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;book&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;object&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_key-value"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;Book&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;&lt;span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby"&gt;new&lt;/span&gt; 
&lt;span class="linenum"&gt; 4&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt; 
&lt;span class="linenum"&gt; 5&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Il codice di &lt;em&gt;/app/views/authors/_book.html.erb&lt;/em&gt; è il seguente:&lt;/p&gt;
&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="text text_html text_html_ruby"&gt;&lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;div&lt;/span&gt; &lt;span class="entity entity_other entity_other_attribute-name entity_other_attribute-name_html"&gt;class&lt;/span&gt;=&lt;span class="string string_quoted string_quoted_double string_quoted_double_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_html"&gt;"&lt;/span&gt;book&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_html"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; 
&lt;span class="linenum"&gt; 2&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%&lt;/span&gt; new_or_existing &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; book&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;new_record? &lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby"&gt;?&lt;/span&gt; &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;new&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;:&lt;/span&gt; &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;existing&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt; 
&lt;span class="linenum"&gt; 3&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%&lt;/span&gt; prefix &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;author[&lt;span class="source source_ruby source_ruby_embedded source_ruby_embedded_source"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;#{&lt;/span&gt;new_or_existing&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;}&lt;/span&gt;&lt;/span&gt;_book_attributes][]&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt; 
&lt;span class="linenum"&gt; 4&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%&lt;/span&gt; fields_for prefix&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; book &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do &lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt;&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;book_form&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;-%&amp;gt;&lt;/span&gt;&lt;/span&gt; 
&lt;span class="linenum"&gt; 5&lt;/span&gt; &lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;p&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; 
&lt;span class="linenum"&gt; 6&lt;/span&gt; Titolo: &lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%=&lt;/span&gt; book_form&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;text_field &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;title&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt; 
&lt;span class="linenum"&gt; 7&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%=&lt;/span&gt; link_to_function &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;remove&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;$(this).up('.book').remove()&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt; 
&lt;span class="linenum"&gt; 8&lt;/span&gt; &lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;p&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; 
&lt;span class="linenum"&gt; 9&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;-%&amp;gt;&lt;/span&gt;&lt;/span&gt; 
&lt;span class="linenum"&gt; 10&lt;/span&gt; &lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;div&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;La &lt;strong&gt;chiave&lt;/strong&gt; sta nell’helper &lt;em&gt;fields_for&lt;/em&gt; (riga 4) che si comporta in maniera molto simile a &lt;em&gt;form_for&lt;/em&gt;, ovvero renderizza tutti i campi dell’oggetto cui si riferisce ma senza racchiuderli in un tag &lt;em&gt;form&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;A questo punto basta definire opportunamente i metodi &lt;em&gt;new_book_attributes&lt;/em&gt; e &lt;em&gt;existing_book_attributes&lt;/em&gt;, oltre alla callback &lt;em&gt;save_books&lt;/em&gt;, in &lt;em&gt;/app/models/author.rb&lt;/em&gt;:&lt;/p&gt;
&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails"&gt;&lt;span class="support support_function support_function_activerecord support_function_activerecord_rails"&gt;after_update&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;save_books&lt;/span&gt;
&lt;span class="linenum"&gt; 2&lt;/span&gt; 
&lt;span class="linenum"&gt; 3&lt;/span&gt; &lt;span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;new_book_attributes=&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby"&gt;(&lt;/span&gt;&lt;span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby"&gt;book_attributes&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby"&gt;)&lt;/span&gt;&lt;/span&gt; 
&lt;span class="linenum"&gt; 4&lt;/span&gt; book_attributes&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;each &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do &lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt;&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;attributes&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt; 
&lt;span class="linenum"&gt; 5&lt;/span&gt; books&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;build&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;attributes&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt; 
&lt;span class="linenum"&gt; 6&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt; 
&lt;span class="linenum"&gt; 7&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;
&lt;span class="linenum"&gt; 8&lt;/span&gt; 
&lt;span class="linenum"&gt; 9&lt;/span&gt; &lt;span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;existing_book_attributes=&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby"&gt;(&lt;/span&gt;&lt;span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby"&gt;book_attributes&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby"&gt;)&lt;/span&gt;&lt;/span&gt; 
&lt;span class="linenum"&gt; 10&lt;/span&gt; books&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;reject&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby"&gt;&amp;amp;&lt;/span&gt;&lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;new_record?&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;each &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do &lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt;&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;book&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt; 
&lt;span class="linenum"&gt; 11&lt;/span&gt; attributes &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; book_attributes&lt;span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby"&gt;[&lt;/span&gt;book&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;id&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;to_s&lt;span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby"&gt;]&lt;/span&gt; 
&lt;span class="linenum"&gt; 12&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;if&lt;/span&gt; attributes 
&lt;span class="linenum"&gt; 13&lt;/span&gt; book&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;attributes &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; attributes 
&lt;span class="linenum"&gt; 14&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;else&lt;/span&gt; 
&lt;span class="linenum"&gt; 15&lt;/span&gt; books&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;delete&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;book&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt; 
&lt;span class="linenum"&gt; 16&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt; 
&lt;span class="linenum"&gt; 17&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt; 
&lt;span class="linenum"&gt; 18&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt; 
&lt;span class="linenum"&gt; 19&lt;/span&gt; 
&lt;span class="linenum"&gt; 20&lt;/span&gt; &lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;save_books&lt;/span&gt;&lt;/span&gt; 
&lt;span class="linenum"&gt; 21&lt;/span&gt; books&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;each &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do &lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt;&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;book&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt; 
&lt;span class="linenum"&gt; 22&lt;/span&gt; book&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;save&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="constant constant_language constant_language_ruby"&gt;false&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt; 
&lt;span class="linenum"&gt; 23&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt; 
&lt;span class="linenum"&gt; 24&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Le action &lt;em&gt;edit&lt;/em&gt; e &lt;em&gt;create&lt;/em&gt; in &lt;em&gt;/app/controllers/authors_controller.rb&lt;/em&gt; sono quelle “classiche”. La action &lt;em&gt;update&lt;/em&gt; deve essere invece dotata di un accorgimento per fare in modo che tutto funzioni anche nel caso in cui vengano rimossi dalla form &lt;strong&gt;tutti&lt;/strong&gt; i &lt;em&gt;book&lt;/em&gt;:&lt;/p&gt;
&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails"&gt;&lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;update&lt;/span&gt;&lt;/span&gt; 
&lt;span class="linenum"&gt; 2&lt;/span&gt; params&lt;span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby"&gt;[&lt;/span&gt;&lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;author&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby"&gt;][&lt;/span&gt;&lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;existing_book_attributes&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby"&gt;]&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby"&gt;||=&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby"&gt;{}&lt;/span&gt; 
&lt;span class="linenum"&gt; 3&lt;/span&gt; 
&lt;span class="linenum"&gt; 4&lt;/span&gt; &lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt; &lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby"&gt;#&lt;/span&gt; salvataggio "classico" di @author
&lt;/span&gt;&lt;span class="linenum"&gt; 5&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Questo tutorial è stato riadattato a partire da alcuni &lt;a href="http://railscasts.com"&gt;screencast di Ryan Bates&lt;/a&gt; (episodi 73, 74, 75). Nei nostri progetti abbiamo utilizzato questo sistema per permettere all’utente il caricamento simultaneo di più immagini associate ad un oggetto (utilizzando il &lt;a href="http://svn.techno-weenie.net/projects/plugins/attachment_fu/"&gt;plugin attachment_fu&lt;/a&gt;), sistema che abbiamo intenzione di evolvere attraverso l’utilizzo di &lt;a href="http://github.com/Squeegy/fleximage/wikis"&gt;fleximage&lt;/a&gt; e &lt;a href="http://swfupload.org/"&gt;swfupload&lt;/a&gt; per ottenere la progress bar degli allegati in upload e la loro validazione &lt;strong&gt;prima&lt;/strong&gt; del loro effettivo caricamento.&lt;/p&gt;</description><link>http://blog.ateapick.com/post/1166353562</link><guid>http://blog.ateapick.com/post/1166353562</guid><pubDate>Tue, 23 Sep 2008 00:00:00 +0200</pubDate><category>form</category><category>plugin</category><category>rails</category><category>ruby</category><dc:creator>dando76</dc:creator></item><item><title>Google Chrome e le applicazioni web</title><description>&lt;p&gt;Da pochi giorni è uscito &lt;a href="http://www.google.com/chrome"&gt;Chrome&lt;/a&gt;, il tanto atteso browser del colosso di Mountain View.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l9557vnPv21qcqixx.png"/&gt;&lt;/p&gt;
&lt;p&gt;Come prevedibile la risonanza mediatica è stata notevole; tra le (più o meno innovative) &lt;a href="http://www.google.com/chrome/intl/it/features.html"&gt;feature&lt;/a&gt; ce n‘è una che ha catturato la mia attenzione più delle altre, ovvero la possibilità di creare delle &lt;strong&gt;scorciatoie per applicazioni web&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Questa funzionalità può apparire non così rilevante ma, a mio parere, è molto significativa poichè &lt;strong&gt;proviene direttamente dal mondo delle applicazioni desktop&lt;/strong&gt;.&lt;br/&gt; Le pagine web stanno diventando &lt;strong&gt;veri e propri software&lt;/strong&gt; e, come tali, hanno bisogno di strumenti di nuova concezione.&lt;/p&gt;
&lt;p&gt;Gli sviluppatori di Google commentano così:&lt;/p&gt;
&lt;p&gt;“Il Web si è evoluto enormemente negli ultimi anni: le semplici pagine di testo hanno lasciato il posto a sofisticate applicazioni interattive, di conseguenza ci siamo subito resi conto che era necessario un ripensamento del concetto stesso di browser. Ciò che avevamo in mente non era semplicemente uno strumento di navigazione, bensì una moderna &lt;strong&gt;piattaforma in cui eseguire pagine e applicazioni web&lt;/strong&gt;. Ed è proprio questo che ci siamo prefissati di realizzare.”&lt;/p&gt;</description><link>http://blog.ateapick.com/post/1166369895</link><guid>http://blog.ateapick.com/post/1166369895</guid><pubDate>Mon, 08 Sep 2008 00:00:00 +0200</pubDate><category>browser</category><category>webapp</category><dc:creator>dando76</dc:creator></item><item><title>Un'alternativa a Globalize: GetText + Model Localization Plugin</title><description>&lt;p&gt;&lt;a href="http://www.globalize-rails.org"&gt;Globalize&lt;/a&gt; è un ottimo plugin che copre tutti gli aspetti legati all’internazionalizzazione di un’applicazione &lt;a href="http://www.rubyonrails.org"&gt;Rails&lt;/a&gt;, tra cui:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Traduzione dei testi “statici” (&lt;em&gt;View Translations&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Traduzione dei testi “dinamici” (&lt;em&gt;Model Translations&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Localizzazione di date, numeri, valute etc…&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Il setup del plugin provvede alla crazione di &lt;strong&gt;3 tabelle&lt;/strong&gt; sul database già popolate con le informazioni di localizzazione relative a &lt;strong&gt;239 paesi&lt;/strong&gt; e con le traduzioni comuni (es. giorni della settimana) in &lt;strong&gt;186 lingue&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Sia le &lt;em&gt;View Translations&lt;/em&gt; che le &lt;em&gt;Model Translations&lt;/em&gt; vengono scritte sul database ed è possibile, quindi, creare un’area (riservata) dell’applicazione che si occupi esclusivamente del &lt;strong&gt;&lt;span class="caps"&gt;CRUD&lt;/span&gt; delle traduzioni&lt;/strong&gt;, gestibili quindi in autonomia dall’utente finale.&lt;/p&gt;
&lt;p&gt;La necessità di un’&lt;strong&gt;alternativa a Globalize&lt;/strong&gt; è nata col tempo a partire da alcune considerazioni:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;“Ho veramente bisogno delle informazioni di localizzazione di 239 paesi e 186 lingue se il mio sito supporterà al massimo le 5 lingue europee più comuni?”&lt;/li&gt;
&lt;li&gt;“E’ corretto gestire nello stesso modo la traduzione delle parti statiche e dinamiche di un sito?”&lt;/li&gt;
&lt;li&gt;“Sono realmente necessari tutti gli accessi al database effettuati da Globalize per la localizzazione?”&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Le risposte, nel mio caso, credo siano a questo punto evidenti; in particolare ritengo che ci sia una sostanziale differenza tra i due tipi di traduzioni che giustifica la ricerca di &lt;strong&gt;due soluzioni diverse&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Per le &lt;strong&gt;traduzioni statiche&lt;/strong&gt; ho scelto (ad oggi con soddisfazione) di utilizzare &lt;a href="http://www.gnu.org/software/gettext/"&gt;GetText&lt;/a&gt; e la sua &lt;a href="http://www.yotabanana.com/hiki/ruby-gettext.html"&gt;implementazione in ruby&lt;/a&gt;. A &lt;a href="http://manuals.rubyonrails.com/read/chapter/105"&gt;questo&lt;/a&gt; indirizzo è disponibilie una guida molto chiara da cui iniziare.&lt;/p&gt;
&lt;p&gt;Per le &lt;strong&gt;traduzioni dinamiche&lt;/strong&gt; non sono riuscito a trovare niente di adeguato alle mie esigenze per cui ho scritto un &lt;a href="http://sempronio.dyndns.org/txpblog/file_download/1/model_localization.zip"&gt;plugin per la localizzazione dei modelli&lt;/a&gt; che, unito a GetText, completa la soluzione all’internazionalizzazione da me adottata.&lt;/p&gt;
&lt;p&gt;Il suo funzionamento è molto semplice. Supponiamo di avere il model &lt;em&gt;Task&lt;/em&gt; con un attributo &lt;em&gt;name&lt;/em&gt; che vogliamo rendere traducibile in inglese e francese.&lt;/p&gt;
&lt;p&gt;Attraverso una migrazione aggiungiamo gli attributi che conterranno le 2 traduzioni:&lt;/p&gt;

&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails"&gt;&lt;span class="meta meta_class meta_class_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_class keyword_control_class_ruby"&gt;class&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby"&gt;AddTranslationsToTaskName&lt;span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby"&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_inheritance punctuation_separator_inheritance_ruby"&gt;&amp;lt;&lt;/span&gt; ActiveRecord::Migration&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 2&lt;/span&gt; &lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;self.up&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 3&lt;/span&gt; add_column &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;tasks&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;name_en&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;string&lt;/span&gt;
&lt;span class="linenum"&gt; 4&lt;/span&gt; add_column &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;tasks&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;name_fr&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;string&lt;/span&gt;
&lt;span class="linenum"&gt; 5&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;
&lt;span class="linenum"&gt; 6&lt;/span&gt; 
&lt;span class="linenum"&gt; 7&lt;/span&gt; &lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;self.down&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 8&lt;/span&gt; remove_column &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;tasks&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;name_en&lt;/span&gt;
&lt;span class="linenum"&gt; 9&lt;/span&gt; remove_column &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;tasks&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;name_fr&lt;/span&gt;
&lt;span class="linenum"&gt; 10&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;
&lt;span class="linenum"&gt; 11&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Il plugin estende &lt;em&gt;ActiveRecord&lt;/em&gt; definendo il metodo &lt;em&gt;localize&lt;/em&gt; che si usa così:&lt;/p&gt;

&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails"&gt;&lt;span class="meta meta_rails meta_rails_model"&gt;&lt;span class="meta meta_class meta_class_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_class keyword_control_class_ruby"&gt;class&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby"&gt;Task&lt;span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby"&gt; &lt;span class="punctuation punctuation_separator punctuation_separator_inheritance punctuation_separator_inheritance_ruby"&gt;&amp;lt;&lt;/span&gt; ActiveRecord::Base&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 2&lt;/span&gt; localize &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;name&lt;/span&gt;
&lt;/span&gt;&lt;span class="linenum"&gt; 3&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;A questo punto basterà utilizzare l’attributo preceduto da un &lt;em&gt;underscore&lt;/em&gt; (in perfetto stile GetText) sia nelle form, per la modifica (riga 5):&lt;/p&gt;

&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="text text_html text_html_ruby"&gt;&lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;h1&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Editing task&lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;h1&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 2&lt;/span&gt; 
&lt;span class="linenum"&gt; 3&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%&lt;/span&gt; form_for&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby"&gt;@&lt;/span&gt;task&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do &lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt;&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;f&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 4&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%=&lt;/span&gt; f&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;error_messages &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 5&lt;/span&gt; &lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;p&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%=&lt;/span&gt; f&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;text_field &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;_name&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;p&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 6&lt;/span&gt; &lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;p&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 7&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%=&lt;/span&gt; f&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;submit &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;Update&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 8&lt;/span&gt; &lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;p&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 9&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 10&lt;/span&gt; 
&lt;span class="linenum"&gt; 11&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%=&lt;/span&gt; link_to &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;Show&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; &lt;span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby"&gt;@&lt;/span&gt;task&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt; |
&lt;span class="linenum"&gt; 12&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%=&lt;/span&gt; link_to &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;Back&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; tasks_path &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;che in visualizzazione (riga 3):&lt;/p&gt;

&lt;pre class="textmate-source"&gt;&lt;span class="linenum"&gt; 1&lt;/span&gt; &lt;span class="text text_html text_html_ruby"&gt;&lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;h1&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Showing task&lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;h1&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 2&lt;/span&gt; 
&lt;span class="linenum"&gt; 3&lt;/span&gt; &lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;p&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%=&lt;/span&gt;&lt;span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby"&gt;@&lt;/span&gt;task&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;_name&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_tag meta_tag_block meta_tag_block_any meta_tag_block_any_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_block entity_name_tag_block_any entity_name_tag_block_any_html"&gt;p&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="linenum"&gt; 4&lt;/span&gt; 
&lt;span class="linenum"&gt; 5&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%=&lt;/span&gt; link_to &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;Edit&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; edit_task_path&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby"&gt;@&lt;/span&gt;task&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt; |
&lt;span class="linenum"&gt; 6&lt;/span&gt; &lt;span class="source source_ruby source_ruby_rails source_ruby_rails_embedded source_ruby_rails_embedded_html"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;&amp;lt;%=&lt;/span&gt; link_to &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;Back&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; tasks_path &lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;La lingua in cui viene modificato o visualizzato l’attributo è la lingua corrente.&lt;/p&gt;
&lt;p&gt;Chiaramente nel momento in cui dovessi affrontare lo sviluppo di un’applicazione in 20 lingue, tra cui l’arabo e il giapponese, tornerei a prendere in seria considerazione l’adozione di Globalize!&lt;/p&gt;</description><link>http://blog.ateapick.com/post/1166379692</link><guid>http://blog.ateapick.com/post/1166379692</guid><pubDate>Tue, 02 Sep 2008 00:00:00 +0200</pubDate><category>gettext</category><category>globalize</category><category>i18n</category><category>l10n</category><category>plugin</category><category>rails</category><dc:creator>dando76</dc:creator></item><item><title>RESTful (Rails) Development</title><description>&lt;p&gt;&lt;span class="caps"&gt;REST&lt;/span&gt; è un acronimo introdotto nel 2000 da Roy Fielding, uno dei principali autori del protocollo &lt;span class="caps"&gt;HTTP&lt;/span&gt;, che identifica uno stile di architettura per sistemi distribuiti (come il World Wide Web) incentrato sul concetto di &lt;strong&gt;risorsa&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Una risorsa è una qualsiasi entità identificabile (univocamente) da un’&lt;span class="caps"&gt;URL&lt;/span&gt;, manipolabile attraverso uno dei &lt;strong&gt;4 verbi&lt;/strong&gt; dell’http (get, post, put, delete) e indipendente dalla sua rappresentazione. Consideriamo ad esempio la risorsa identificata dall’&lt;span class="caps"&gt;URL&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;a href="http://www.ateapick.com/people/filippo"&gt;http://www.ateapick.com/people/filippo&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Attraverso i 4 verbi dell’&lt;span class="caps"&gt;HTTP&lt;/span&gt; posso manipolare (&lt;strong&gt;&lt;span class="caps"&gt;CRUD&lt;/span&gt;&lt;/strong&gt;) la risorsa secondo le seguenti convenzioni:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;POST&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt; &lt;a href="http://www.ateapick.com/people/filippo"&gt;http://www.ateapick.com/people/filippo&lt;/a&gt;             (C)                               &lt;strong&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;GET&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt; &lt;a href="http://www.ateapick.com/people/filippo"&gt;http://www.ateapick.com/people/filippo&lt;/a&gt;             (R)                               &lt;strong&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;PUT&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt; &lt;a href="http://www.ateapick.com/people/filippo"&gt;http://www.ateapick.com/people/filippo&lt;/a&gt;             (U)                               &lt;strong&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;DELETE&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt; &lt;a href="http://www.ateapick.com/people/filippo"&gt;http://www.ateapick.com/people/filippo&lt;/a&gt;             (D)&lt;/p&gt;
&lt;p&gt;Posso inoltre ottenere diverse rappresentazioni della &lt;strong&gt;stessa&lt;/strong&gt; risorsa discriminando la richiesta tramite il mime-type:&lt;/p&gt;
&lt;p&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;GET&lt;/span&gt;&lt;/span&gt; &lt;a href="http://www.ateapick.com/people/filippo"&gt;http://www.ateapick.com/people/filippo&lt;/a&gt; (&lt;strong&gt;html&lt;/strong&gt;)                               &lt;span class="caps"&gt;&lt;span class="caps"&gt;GET&lt;/span&gt;&lt;/span&gt; &lt;a href="http://www.ateapick.com/people/filippo."&gt;http://www.ateapick.com/people/filippo.&lt;/a&gt;&lt;strong&gt;xml&lt;/strong&gt; &lt;span class="caps"&gt;&lt;span class="caps"&gt;GET&lt;/span&gt;&lt;/span&gt; &lt;a href="http://www.ateapick.com/people/filippo."&gt;http://www.ateapick.com/people/filippo.&lt;/a&gt;&lt;strong&gt;rss&lt;/strong&gt; &lt;span class="caps"&gt;&lt;span class="caps"&gt;GET&lt;/span&gt;&lt;/span&gt; &lt;a href="http://www.ateapick.com/people/filippo."&gt;http://www.ateapick.com/people/filippo.&lt;/a&gt;&lt;strong&gt;iphone&lt;/strong&gt; &lt;span class="caps"&gt;&lt;span class="caps"&gt;GET&lt;/span&gt;&lt;/span&gt; &lt;a href="http://www.ateapick.com/people/filippo."&gt;http://www.ateapick.com/people/filippo.&lt;/a&gt;&lt;strong&gt;wii&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Rails 1.2&amp;#160;ha introdotto il supporto allo sviluppo &lt;span class="caps"&gt;REST&lt;/span&gt; attraverso un sistema di routing che tiene in considerazione il verbo &lt;span class="caps"&gt;HTTP&lt;/span&gt; utilizzato nella richiesta dell’&lt;span class="caps"&gt;URL&lt;/span&gt;. Le diverse rappresentazioni di una risorsa si possono invece ottenere utilizzando l’instance method &lt;em&gt;respond_to&lt;/em&gt; di &lt;em&gt;ActionController::MimeResponds&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Con il rilascio di &lt;strong&gt;Rails 2.0&lt;/strong&gt; il paradigma &lt;span class="caps"&gt;REST&lt;/span&gt; ha assunto un ruolo ancor più importante nel framework: chiari segnali sono il nuovo scaffolding e il nuovo modo di nominare i file della view che esplicita la creazione di diverse rappresentazioni basate sui mime-type.&lt;/p&gt;
&lt;p&gt;Esistono molti documenti che trattano in maniera approfondita l’argomento. Un’ottima guida introduttiva sullo sviluppo &lt;span class="caps"&gt;REST&lt;/span&gt;ful in Rails può essere scaricata a &lt;a href="http://www.b-simple.de/download/restful_rails_en.pdf"&gt;questo indirizzo&lt;/a&gt;. Da un po’ di tempo ormai ho fatto mio questo stile di programmazione e, una volta superate le prime difficoltà di “ambientazione”, ho cominciato ad assaporarne tutti i vantaggi: oggi considero le linee guida scelte per il rilascio di Rails2 una consacrazione della qualità e della lungimiranza di questo framework.&lt;/p&gt;
&lt;p&gt;Oltre a veicolare lo sviluppo di applicazioni secondo il pattern &lt;span class="caps"&gt;MVC&lt;/span&gt;, il &lt;span class="caps"&gt;REST&lt;/span&gt;ful Rails impone un’ulteriore disciplina nella codifica che garantisce maggiore compattezza, migliore leggibilità, “pretty-urling” e semplicità nella costruzione di &lt;span class="caps"&gt;API&lt;/span&gt;. Pensare ad un’applicazione orientata al &lt;span class="caps"&gt;CRUD&lt;/span&gt; di risorse inizialmente può destare delle perplessità:&lt;/p&gt;
&lt;p&gt;“non è un approccio limitato? In una webapp molto spesso ho bisogno di altre azioni rispetto alla semplice creazione, visualizzazione, modifica o cancellazione di una risorsa…”&lt;/p&gt;
&lt;p&gt;In realtà dipende da come si interpreta l’applicazione stessa. Un’azione molto comune come la &lt;em&gt;login&lt;/em&gt; da parte di un &lt;em&gt;utente&lt;/em&gt;, ad esempio, rientra perfettamente nell’approccio &lt;span class="caps"&gt;REST&lt;/span&gt; se pensata piuttosto come la &lt;em&gt;creazione&lt;/em&gt; di una &lt;em&gt;sessione&lt;/em&gt;; specularmente la &lt;em&gt;logout&lt;/em&gt; corrisponde alla &lt;em&gt;distruzione&lt;/em&gt; di una &lt;em&gt;sessione&lt;/em&gt;; in definitiva il concetto di risorsa è talmente generico che con un minimo di sforzo di astrazione può essere adattato a qualsiasi modello.&lt;/p&gt;
&lt;p&gt;Riguardo alla lungimiranza, l’impronta &lt;span class="caps"&gt;REST&lt;/span&gt;ful così marcata del nuovo Rails pone ancor più il framework come scelta azzeccata per chi vuol fare &lt;strong&gt;web 2.0&lt;/strong&gt; e per chi vuol seguire la cordata di progetti che rappresentano i primi passi verso la costruzione del cosiddetto &lt;strong&gt;web semantico&lt;/strong&gt;. Mi riferisco a progetti come &lt;a href="http://openid.net/"&gt;OpenID&lt;/a&gt;, un network distribuito e decentralizzato, nel quale la tua identità è un &lt;span class="caps"&gt;URL&lt;/span&gt; e può essere verificata da qualunque server supporti questo protocollo, o come &lt;a href="http://en.gravatar.com/"&gt;Gravatar&lt;/a&gt; secondo il quale è il tuo avatar ad essere identificato da un’&lt;span class="caps"&gt;URL&lt;/span&gt; sull’intero web.&lt;/p&gt;
&lt;p&gt;Se poi consideriamo anche le &lt;strong&gt;relazioni tra le risorse&lt;/strong&gt; descritte attraverso &lt;a href="http://gmpg.org/xfn/"&gt;&lt;span class="caps"&gt;XFN&lt;/span&gt;&lt;/a&gt; e &lt;a href="http://www.foaf-project.org/"&gt;&lt;span class="caps"&gt;FOAF&lt;/span&gt;&lt;/a&gt; entriamo nel vasto campo delle &lt;strong&gt;Reti Sociali&lt;/strong&gt; con un’apertura tale per cui perfino Google &lt;a href="http://code.google.com/apis/socialgraph/"&gt;si accorgerà&lt;/a&gt; delle nostre &lt;em&gt;killer webapp&lt;/em&gt;… ;-)&lt;/p&gt;</description><link>http://blog.ateapick.com/post/1166383790</link><guid>http://blog.ateapick.com/post/1166383790</guid><pubDate>Mon, 01 Sep 2008 00:00:00 +0200</pubDate><category>foaf</category><category>rest</category><category>rails</category><category>xfn</category><dc:creator>dando76</dc:creator></item></channel></rss>

