2. Chi vi parla
● Alessandro `jekil` Tanasi
● Vede persone e fa cose
● Non sviluppa siti web ma ha delle web-
esigenze da soddisfare (chi non le ha?)
● Senza perdere tempo e nel modo più
efficace possibile
4. Ruby on Rails - fu?
“Ruby on Rails is astounding. Using it
is like watching a kung-fu movie,
where a dozen bad-ass frameworks
prepare to beat up the little
newcomer only to be handed their
asses in a variety of imaginative
ways.”
(Nathan Torkington, O'Reilly Program
Chair for OSCON)
5. Ruby on Rails
Ruby on Rails è un framework per lo sviluppo
di applicativi web
● Basato su Ruby
● Open source
● Pensato per massimizzare la produttività
● Progettato pensando alla felicità del
programmatore
● http://rubyonrails.org/screencasts
7. La forza di Rails
● Ruby
● Convention over configuration
● Best practices: MVC, DRY, Testing
● Astrazione (SQL, Javascript, ..)
● Integrazione con AJAX e REST
● Metodologie “agile”
8. Installazione
● Interprete Ruby
– apt-get install ruby
– Compilazione dei sorgenti
– IstantRails su Windows
– Locomotive su OSX
● Ruby on Rails
● DBMS
– SQLite, MySQL, Postgres e altri
● Editor di testo
– TextMate, jEdit, Scite, NetBeans, Aptana,
vim, emacs
12. Migrations
● Evoluzione del database schema nel tempo
● Definite indipendentemente dal DBMS
sottostante
● script/generate migration
● Ogni migrazione è numerata e applicata
sequenzialmente
● La migrazione può essere reversibile
● I dati evolvono con la migrazione
● rake db:migrate VERSION=X
13. Esempio
class CreateUsers < ActiveRecord::Migration
def self.up
create_table quot;usersquot;, :force => true do |t|
t.string :login, :null => false
t.string :email, :null => false
t.string :salt, :null => false, :limit => 40
t.string :remember_token
t.datetime :remember_token_expires_at
t.string :password_reset_code, :limit => 40
t.timestamps
end
add_index :users, :login
add_index :users, :enabled
end
def self.down
drop_table quot;usersquot;
end
end
14. Rake
Utility per lo svolgimento di task
● db:migrate
● db:sessions:create
● doc:app
● doc:rails
● log:clear
● rails:freeze:gems
● rails:freeze:edge
● rails:update
● :test (default task)
● :stats
16. Scaffold
● Creazione automatizzata dell'interfaccia
web di un dato modello
● Utile per strumenti che devono essere
usabili da subito e con il minimo sforzo
● Possibilità di personalizzazioni
● Rapidità di sviluppo
● ruby script/generate scaffold antani
18. ActiveRecord
● Ogni tabella del database è mappata con
una classe
● I nomi delle tabelle sono al plurale mentre
le classi dei modelli sono al singolare
● Ogni tabella ha un campo primary key
chiamato id
● La mappatura permette di eseguire
operazioni trattando i dati come oggetti
● Permette di definire costrutti e condizioni
sui dati
21. Validazioni
● Regole di validazione del modello che
proteggono l'integrità dei dati
● La validazione viene eseguita al
salvattaggio e modifica di dati
● E' fondamentale che ogni dato sia sempre
validato
● Es. nomi utente univoci
● Es. campi che devono essere solo numerici
25. ActiveController
● I controller sono classi Ruby in
app/controllers
● Ad ogni suo metodo pubblico corrisponde
una vista
● Gestiscono le azioni che si compiono sui
dati
● Gestiscono tutte le interazioni logiche
● Es. un utente compra un oggetto
● Es. un utente si iscrive al sito
26. Flash messages
● Permettono di impostare un messaggio da
mostrare all'utente nella gestione di una
richiesta e visualizzarlo nella successiva
● Varie priorità flash[:notice], flash[:error]
● Utilizzati per azioni che richiedono un
feedback dopo un submit
● Es. Compilazione di un ordine online
● Es. Login di un utente
27. Esempio
class LinksController < ApplicationController
def index
@user = User.find_by_id(params[:user_id])
@links = @user.links
end
def latest
n = 10
@links = Link.find(:all, :order => 'created_at ASC', :limit => n)
end
end
29. ActionView
● Si occupa del rendering della risposta al
client
● Rendering basato su template
● Permesso l'uso di codice all'interno dei
template
● Il controller sceglie quale template
visualizzare
● Le view hanno accesso alle variabili
d'istanza (ad es. @pluto)
30. Tipi di template
● Rxml – genera output XML. Tipicamente
usato per generare feed RSS/Atom
● Rhtml – genera output HTML
● Rjs – genera codice Javascript. Utilizzato
per AJAX
31. HTML template
● <%= ruby code %> valuta l'espressione e
stampa l'output
● <%= ruby code -%> valuta l'espressione e
stampa l'output senza un newline a fine
riga
● <% ruby code %> valuta l'espressione e
non stampa l'output
● <%= h comment.body %> escaping
dell'output
32. Partials
● Parti di una pagina (ad es. footer)
● Possono essere inclusi in una o più pagine
● Funzionano come i template
● Il loro nome inizia con un underscore
● Vengono utilizzate per le parti di codice
condivise che devono essere riciclate
nell'applicazione
● Es. search box
● Es. header e footer
33. Layout
● I template del layout si trovano in
/app/views/layout
● Il posizionamento di tag permette la
visualizzazione delle parti di codice
generate
● <%= yield %> visualizza l'output di una
view
● Permettono di uniformare il layout del sito
e se desiderato di personalizzarlo in alcune
sue zone
36. Helpers
● Moduli Ruby che definiscono metodi
disponibili nei template
● Evitano duplicazione di codice
● Riducono il codice nei template
● Per default ogni controller ha un helper
corrispondente
● Usati per definire le funzionalità comuni
● Es. è loggato un utente?
● Es. pagina successiva
37. Esempio
module ApplicationHelper
# Check if a parameter is nil, if it's print - else print the value. NilPrintCheck
def npc(var)
if var.nil? or var.empty?
return '-'
else
return var
end
end
39. Testing
● Test::Unit è una libreria Ruby per unit
testing
● Rails integra tre tipi di tests:
– Uni tests (test sul modello)
– Integration tests (test di integrazione)
– Functional tests (test sul controller)
● Ogni test deve iniziare per test_
● Prima dell'esecuzione di ogni test viene
chiamato il medoto setup e alla sua
conclusione il metodo teardown
● Ogni test contiene una o piu assert
40. Unit Testing
● Ogni modello ha il suo unit test in
test/units/test_my_model.rb generato
automaticamente alla creazione del
modello
● Utilizzato per verifcare coerenza di
– Modello
– Validatori
– Funzioni del modello
● E' buona norma testare ogni funzione del
modello in particolare quelle custom
41. Esempio
require File.dirname(__FILE__) + '/../test_helper'
class UserTest < Test::Unit::TestCase
fixtures :users
def test_password_chars
assert_difference 'User.count' do
u = create_user(:login => '0aaaaaaaA-_')
end
assert_no_difference 'User.count' do
u = create_user(:login => 'aaaaaaaaaaa+')
assert u.errors.on(:login)
end
end
def test_should_create_user
assert_difference 'User.count' do
user = create_user
assert !user.new_record?, quot;#{user.errors.full_messages.to_sentence}quot;
end
end
end
42. Helpers & Fixtures
● Ogni unit test ha il suo helper
● E' possibile utilizzare una fixture che
contiene i dati di test che vengono caricati
nel database
● Dati memorizzati in sintassi YAML
● Permette di avere uno storage di dati
d'esempio
43. Esempio
quentin:
id: 1
login: quentin
email: quentin@example.com
created_at: <%= 5.days.ago.to_s :db %>
aaron:
id: 2
login: aaron
email: aaron@example.com
bio: Aaron is a weird guy
created_at: <%= 1.days.ago.to_s :db %>
45. Functional tests
● Verificano un'istanza di controller
● Simula una richiesta HTTP e controlla la
risposta
● Fatti per verificare il funzionamento della
logica applicativa
46. Esempio
require File.dirname(__FILE__) + '/../test_helper'
require 'comments_controller'
class CommentsController; def rescue_action(e) raise e end; end
class CommentsControllerTest < Test::Unit::TestCase
fixtures :users, :comments
def setup
@controller = CommentsController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@request.env['HTTP_HOST'] = quot;localhostquot;
@request.session[:user] = users(:aaron)
end
def test_rss
get :rss, :id => users(:quentin)
assert_response :success
assert_select quot;rss > channelquot; do
assert_select quot;titlequot;, /Recent comments/
assert_select quot;itemquot;, 1
assert_select quot;item > titlequot;, Regexp.new(users(:aaron).login)
users(:quentin).comments.first.body
end
end
48. Integration tests
● Test di integrazione al Rails dispatcher e
tutti i controller
● Simula scenari d'uso reali
● Inludono le stesse funzionalità dei
functional tests
● Simulano l'utilizzo dei componenti nella
loro globalità
49. Esempio
class TracerBulletTest < ActionController::IntegrationTest
def test_tracer_bullet
get(quot;/mcm/user/loginquot;)
assert_response :success
post(quot;/mcm/user/loginquot;, :email => self.mail, :password
=> self.password)
assert_redirected_to :controller => 'mcm/general'
follow_redirect!
assert_response :success
expect_count = contacts(:adam_sandler).jobs.size
post(quot;/mcm/contacts/searchquot;, :q => 'sandler new york')
assert_response :success
assert_n_search_results(expect_count)
get quot;/mcm/lists/show/#{list.id}quot;
assert_response :success
assert_template 'mcm/lists/show'
end
end
51. RCOV
● Rcov e` una libreria Ruby per misurare la
copertura data dalle unit tests
● Utilizzata per trovare parti rimaste scoperte
dai test
# Installation of rcov:
gem install rcov
ruby script/plugin install http://svn.codahale.com/rails_rcov
rake test:test:rcov
53. Routing
● Insime di regole che mappano URL e
parametri in componenti Rails
● Le rotte sono definite in config/routes.rb
● Se un URL non trova una rotts
corrispondente si ottiene un 404
● Gli oggetti e i controller possono essere
mappati sugli URL per creare ad es. /users/
photos/1
55. MVC Request Cycle
1.Richiesta http://localhost:3000/users/new/1
2.Il server Rails:
1.Invoca il dispatcher
2.Cerca la rotta in routes.rb
3.La rotta di default :controller/:action/:id
viene usata se non ne vengono trovate
altre
4.Il metodo new è chiamato all'interno del
controller users che prendo il dato ad id
1 dal modello
3.Viene generato codice HTML dalla vista
new.html.erb
4.Rails invia tutto il codice HTML generato al
browser
57. Deployment
● Utilizzo di normali web server e CGI
(fastCGI)
● Utilizzo di cluster (mongrel) e web server di
front end in modalita` proxy (apache)
● Utilizzo di tool per il deploy automatico
(Capistrano)
● Il deploy e il mantenimento potrebbe
risultare un tallone d'Achille se non
vengono svolti utilizzando procedure
corrette e lungimiranti
58. Best pratices
● Usare SQL solo se strettamente necessario
● Mettere meno codice possibile nel
controller e cercare di tenere logica nel
modello
● Accedere ai dati utilizzando l'utente
corrente se possibile (ad es.
current_user.visits.recent)
● Dipendere il meno possibile da librerie e
plugin esterni (inluderle nell'applicazione)
● Utilizzare ampiamente le unit test
● Automatizzare ogni task possibile
60. Libri utili
● Agile Web Development with Rails
● Professional Ruby on Rails – Wrox
● Rails Cookbook – O'Reilly
● Deploying Rails Applications - Pragmatic
Bookshelf
● Beginning Ruby on Rails - Wrox