• Save
Sviluppo web con Ruby on Rails
Upcoming SlideShare
Loading in...5
×
 

Sviluppo web con Ruby on Rails

on

  • 5,799 views

Creare un sito web con Ruby on Rails

Creare un sito web con Ruby on Rails

Statistics

Views

Total Views
5,799
Slideshare-icon Views on SlideShare
5,710
Embed Views
89

Actions

Likes
5
Downloads
0
Comments
0

5 Embeds 89

http://www.tanasi.it 60
http://www.slideshare.net 17
http://www.lonerunners.net 9
https://www.linkedin.com 2
http://static.slidesharecdn.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Sviluppo web con Ruby on Rails Sviluppo web con Ruby on Rails Presentation Transcript

    • Sviluppo web con Ruby on Rails
    • 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
    • Ruby on Rails
    • 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)
    • 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
    • Perchè Rails...
    • La forza di Rails ● Ruby ● Convention over configuration ● Best practices: MVC, DRY, Testing ● Astrazione (SQL, Javascript, ..) ● Integrazione con AJAX e REST ● Metodologie “agile”
    • 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
    • Let's go!
    • Struttura directory app controllers helpers models views layouts config environment.rb routes.rb db database.yml migrations lib log public script test vendor plugins rails
    • Migrations
    • 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
    • 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
    • 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
    • Scaffolding
    • 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
    • Modelli
    • 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
    • Finders ● User.find(:all) ● User.find(:all, :limit => 10) ● Dynamic finders ● User.find_all_by_last_name “Hanson” ● User.find_by_age “20” ● User.find_by_first_name_and_last_name “Andreas”, “Kviby”
    • Associazioni has_one :credit_card, :dependent => :destroy has_many :comments, :include => :author has_many :people, :class_name => quot;Personquot;, :conditions => quot;deleted = 0quot;, :order => quot;namequot; has_many :tracks, :order => quot;positionquot;, :dependent => :destroy has_many :comments, :dependent => :nullify has_many :tags, :as => :taggable has_many :subscribers, :through => :subscriptions, :source => :user has_many :subscribers, :class_name => quot;Personquot;, :finder_sql => 'SELECT DISTINCT people.* ' + 'FROM people p, post_subscriptions ps ' + 'WHERE ps.post_id = #{id} AND ps.person_id = p.id ' + 'ORDER BY p.first_name'
    • 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
    • Validatori ● validates_acceptance_of ● validate_associated ● validates_confirmation_of ● validates_each ● validates_exclusion_of ● validates_format_of ● validates_inclusion_of ● validates_length_of ● validates_numericality_of ● validates_presence_of ● validates_size_of ● validates_uniqueness_of
    • Esempio class User < ActiveRecord::Base validates_presence_of :login, :email validates_presence_of :password, :if => :password_required? validates_presence_of :password_confirmation, :if => :password_required? validates_length_of :login, :within => 3..40 validates_length_of :email, :within => 3..100 validates_uniqueness_of :login, :email, :case_sensitive => false validates_format_of :email, :with => /^([^@s]+)@((?:[-a-z0-9]+.)+[a-z]{2,}) $/i, :message => quot;Indirizzo email non validoquot; validates_format_of :login, :with => /^[wd-_]+$/, :message => quot;Sono permessi solo letterequot; before_save :encrypt_password has_one :country has_many :photos has_one :profile, :dependent => :nullify
    • Controller
    • 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
    • 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
    • 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
    • Views
    • 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)
    • 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
    • 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
    • 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
    • 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
    • Esempio <div class=quot;titlesectionquot;> <%= link_to '<img src=quot;/images/rss_rotated.jpgquot; />', :controller => 'rss', :action => 'category', :id => 1 %> Papers </div> <%= render :partial => 'table' %> <p class=quot;readmorequot;><%= link_to 'more papers', :controller => 'documents', :action => 'category', :id => 1 %></p> <div class=quot;titlesectionquot;> <%= link_to '<img src=quot;/images/rss_rotated.jpgquot; />', :controller => 'rss', :action => 'category', :id => 2 %> Slides </div> <%= render :partial => 'table' %> <p class=quot;readmorequot;><%= link_to 'more papers', :controller => 'documents', :action => 'category', :id => 2 %></p> <div class=quot;titlesectionquot;> <%= link_to '<img src=quot;/images/rss_rotated.jpgquot; />', :controller => 'rss', :action => 'category', :id => 3 %> Videos </div>
    • Helpers
    • 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
    • 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
    • Testing
    • 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
    • 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
    • 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
    • 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
    • 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 %>
    • Assertions ● assert(actual, comment) # Asserts truth ● assert_equal(expected, actual, comment) ● assert_in_delta(expected_float, actual_float, delta, ● message) ● assert_match(pattern, string, message) ● assert_nil(object, message)/assert_not_nil ● assert_raise(Exception, ..., message) { block ... } ● assert_difference(expressions, difference = 1, &block)
    • Functional tests ● Verificano un'istanza di controller ● Simula una richiesta HTTP e controlla la risposta ● Fatti per verificare il funzionamento della logica applicativa
    • 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
    • Assertions ● assert_response :success|:redirect|:missing|:error ● assert_redirected_to(:controller => ‘blog’, :action => ‘list’) ● assert_template ‘store/index’ ● assert_not_nil assigns(:items) ● assert session[:user] ● assert_not_nil flash[:notice]
    • 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à
    • 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
    • Running tests ● rake - runs all tests ● rake test:units ● rake test:functionals ● rake test:integration ● ruby test/unit/user_test.rb
    • 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
    • Internals
    • 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
    • MVC Fonte: Manning - Ruby For Rails Ruby Techniques For Railsvelopers
    • 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
    • Deployment
    • 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
    • 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
    • Libri
    • 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
    • Domande
    • Slides e contatti Queste slides sono disponibili su: http://www.lonerunners.net Scrivetemi pure! alessandro@tanasi.it