Sviluppo web con Ruby on Rails

  • 3,543 views
Uploaded on

Creare un sito web con Ruby on Rails

Creare un sito web con Ruby on Rails

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
3,543
On Slideshare
0
From Embeds
0
Number of Embeds
3

Actions

Shares
Downloads
0
Comments
0
Likes
5

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Sviluppo web con Ruby on Rails
  • 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
  • 3. Ruby on Rails
  • 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
  • 6. Perchè Rails...
  • 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
  • 9. Let's go!
  • 10. 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
  • 11. Migrations
  • 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
  • 15. Scaffolding
  • 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
  • 17. Modelli
  • 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
  • 19. 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”
  • 20. 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'
  • 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
  • 22. 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
  • 23. 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
  • 24. Controller
  • 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
  • 28. Views
  • 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
  • 34. 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>
  • 35. Helpers
  • 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
  • 38. Testing
  • 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 %>
  • 44. 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)
  • 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
  • 47. 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]
  • 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
  • 50. Running tests ● rake - runs all tests ● rake test:units ● rake test:functionals ● rake test:integration ● ruby test/unit/user_test.rb
  • 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
  • 52. Internals
  • 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
  • 54. MVC Fonte: Manning - Ruby For Rails Ruby Techniques For Railsvelopers
  • 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
  • 56. Deployment
  • 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
  • 59. Libri
  • 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
  • 61. Domande
  • 62. Slides e contatti Queste slides sono disponibili su: http://www.lonerunners.net Scrivetemi pure! alessandro@tanasi.it