Ruby on Rails   Supinfo 2011
A propos• Martin Catty, fondateur de Synbioz• Rubyiste depuis 2006    _fuse       mcatty@synbioz.com
Ruby avant Rails• Ne partez pas sans vos bagages !• Rails a aidé à l’essor de Ruby• Mais pas de framework sans langage
Ruby     On ne va pas (ou peu) parler de:        I/O        Test                                     VM                   ...
L’Histoire• Créé par Yukihiro Matsumoto (Matz)• Release publique en 2005
Un langage• Plus objet que python• Plus puissant que perl• Fun
Les versions• Stable actuelle: 1.9.2• 1.8.7 dans la branche 1.8• 1.8.7 (p250) fonctionne avec Rails 2 et 3• < 1.8.7 = Rail...
Le fameux hello world  Java          Ruby
Le fameux hello world                Java                           Rubyclass Hello {   public static void main(String [] ...
Le fameux hello world                Java                                          Rubyclass Hello {   public static void ...
Le fameux hello world                Java                                          Rubyclass Hello {   public static void ...
Tout est objet
Tout est objet  2.times { puts "Bonjour Supinfo." }=> Bonjour Supinfo=> Bonjour Supinfo
Tout est objet  2.times { puts "Bonjour Supinfo." }     3.upto(5) { |i| puts i }=> Bonjour Supinfo                      =>...
Tout est objet  2.times { puts "Bonjour Supinfo." }     3.upto(5) { |i| puts i }=> Bonjour Supinfo                      =>...
Tout est objet  2.times { puts "Bonjour Supinfo." }     3.upto(5) { |i| puts i }=> Bonjour Supinfo                      =>...
Les variablesclass A   MAX = 42                           A.new("a")   @@instances = 0         A.new("b")   def initialize...
Itérations
Itérationsa = 1..9for i in a   puts iend
Itérations a = 1..9 for i in a    puts i end=> 1…9
Itérations a = 1..9 for i in a    puts i        ou end=> 1…9
Itérations a = 1..9 for i in a            a = 1..9    puts i        ou   a.each { |i| puts i } end=> 1…9
Itérations a = 1..9 for i in a             a = 1..9    puts i        ou    a.each { |i| puts i } end=> 1…9                ...
Itérations a = 1..9 for i in a                     a = 1..9    puts i                ou    a.each { |i| puts i } end=> 1…9...
Itérations a = 1..9 for i in a                     a = 1..9    puts i                ou    a.each { |i| puts i } end=> 1…9...
Itérations a = 1..9 for i in a                     a = 1..9    puts i                ou    a.each { |i| puts i } end=> 1…9...
Itérations a = 1..9 for i in a                        a = 1..9    puts i                ou       a.each { |i| puts i } end...
Itérations a = 1..9 for i in a                        a = 1..9    puts i                ou       a.each { |i| puts i } end...
Conditions
Conditionsif index == 1else            puts ‘0’ if index.zero?   puts ‘not 0’ unless index.zero?end
Conditionsif index == 1else                       puts ‘0’ if index.zero?     puts ‘not 0’ unless index.zero?enddef what_i...
Tableaux 1/21
Tableaux 1/21   lost = [8, 15, 16, 23]    lost << 42 # push    lost.unshift(4)    # [4, 8, 15, 16, 23, 42]
Tableaux 1/21   lost = [8, 15, 16, 23]    lost << 42 # push    lost.unshift(4)    # [4, 8, 15, 16, 23, 42]
Tableaux 1/21   lost = [8, 15, 16, 23]        lost.at(0)    lost << 42 # push             #4    lost.unshift(4)           ...
Tableaux 1/21   lost = [8, 15, 16, 23]        lost.at(0)    lost << 42 # push             #4    lost.unshift(4)           ...
Tableaux 1/21   lost = [8, 15, 16, 23]        lost.at(0)   lost << nil << nil    lost << 42 # push             #4    lost....
Tableaux 1/21   lost = [8, 15, 16, 23]        lost.at(0)   lost << nil << nil    lost << 42 # push             #4    lost....
Tableaux 1/21   lost = [8, 15, 16, 23]        lost.at(0)   lost << nil << nil    lost << 42 # push             #4    lost....
Tableaux 1/21   lost = [8, 15, 16, 23]        lost.at(0)   lost << nil << nil    lost << 42 # push             #4    lost....
Tableaux 1/21   lost = [8, 15, 16, 23]        lost.at(0)                 lost << nil << nil    lost << 42 # push          ...
Tableaux 1/21   lost = [8, 15, 16, 23]        lost.at(0)                 lost << nil << nil    lost << 42 # push          ...
Tableaux 1/21   lost = [8, 15, 16, 23]        lost.at(0)                 lost << nil << nil    lost << 42 # push          ...
Tableaux 1/21   lost = [8, 15, 16, 23]        lost.at(0)                 lost << nil << nil    lost << 42 # push          ...
Tableaux 1/21   lost = [8, 15, 16, 23]        lost.at(0)                  lost << nil << nil    lost << 42 # push         ...
Tableaux 1/21   lost = [8, 15, 16, 23]        lost.at(0)                  lost << nil << nil    lost << 42 # push         ...
Tableaux 2/2
Tableaux 2/2double_lost = lost.map { |v| v * 2 }# => [8, 16, 30, 32, 46, 84]
Tableaux 2/2                                       # lost: [4, 8, 15, 16, 23, 42]double_lost = lost.map { |v| v * 2 }     ...
Tableaux 2/2                                       # lost: [4, 8, 15, 16, 23, 42]double_lost = lost.map { |v| v * 2 }     ...
Tableaux 2/2                                       # lost: [4, 8, 15, 16, 23, 42]double_lost = lost.map { |v| v * 2 }     ...
String
Stringstr = "bar"puts foo #{str}# => foo #{str}
Stringstr = "bar"         # Interpolationputs foo #{str}   puts "foo #{str}"# => foo #{str}     # => foo bar
Stringstr = "bar"         # Interpolationputs foo #{str}   puts "foo #{str}"# => foo #{str}     # => foo barstr = "a"str.s...
Stringstr = "bar"         # Interpolationputs foo #{str}   puts "foo #{str}"# => foo #{str}     # => foo barstr = "a"     ...
Stringstr = "bar"         # Interpolationputs foo #{str}   puts "foo #{str}"# => foo #{str}     # => foo barstr = "a"     ...
Stringstr = "bar"         # Interpolationputs foo #{str}   puts "foo #{str}"# => foo #{str}     # => foo barstr = "a"     ...
Stringstr = "bar"         # Interpolationputs foo #{str}   puts "foo #{str}"                                           # a...
HashAssociation clé / valeur
HashAssociation clé / valeur h = { :a => a, :b => 42, :c => { :d => f } }   h2 = { :a => foo }                            ...
Class: les constructeurs
Class: les constructeursclass A  def A.new  endendA.new
Class: les constructeursclass A         class B  def A.new       def self.new  end             endend             endA.new...
Class: les constructeursclass A            class B  def A.new          def self.new  end                endend            ...
Class: les constructeursclass A            class B  def A.new          def self.new  end                endend            ...
Class: les accesseurs
Class: les accesseursclass Product   def initialize(name, description, price)      @name = name      @description = descri...
Class: les accesseursclass Product   def initialize(name, description, price)      @name = name      @description = descri...
Class: portée & héritage
Class: portée & héritageclass Animal  def initialize   puts "Born to be alive."  end protected def breathe?  puts "inhale,...
Class: portée & héritageclass Animal                            class Dog < Animal  def initialize                        ...
Class: étendre
Class: étendre# Etendre un objetstr = "foo"class << str  def blank?   self !~ /S/  endendstr.blank?# => false
Class: étendre# Etendre un objet           # Etendre une classestr = "foo"                  class String                  ...
Class: ce qui n’existe pas• Pas d’héritage multiple• Basé sur les mixins• Pas d’interface• Pas de classe abstraite native
Les outilsirb : votre shell ruby [17:59:57] fuse@h [~]$ irb ruby-1.8.7-p302 :001 > puts ‘foo’ foo  => nil ruby-1.8.7-p302 ...
Documentation• http://www.ruby-doc.org/• http://www.ruby-lang.org/• http://apidock.com/ruby• Le pickAxe: LA référence• htt...
RailsOn ne va pas (ou peu) parler de:           Copieurs  Test                   I18n           Rake Cache                ...
L’Histoire• Créé par DHH (David Heinemeier Hansson)• Version 1 en décembre 2005• Pragmatique dès le début: basecamp
Rails en entreprise• Plus un jouet• Présent en entreprise, grandes et petites• Opportunités en temps que développeur
Les versions• Stable actuelle: 3.0.7 • Rails 3 issue du merge avec merb (08/10) • Framework agnostic• Stable actuelle: 2.3...
Des conventionsQuelques noms barbares:• Convention over configuration• DRY• MVC
Convention over      configuration• Votre passion est de customiser Tomcat ?  Désolé !• 0 conf pour commencer à développer ...
Don’t repeat yourself• - de code = - de bug• - de code = - de maintenance• - de code = + de temps
Modèle - Vue - Contrôleur     Modèle     Contrôleur      Vue    Métier    Fonctionnel    Affichage
Rails en vrai• Pas de hello world, c’est trop simple…• La classique liste de produits plutôt.
Créons notre application $ rails app3 environnements
class Product < ActiveRecord::Base   Modèleend                                     app/models/product.rb
class Product < ActiveRecord::Base                 Modèleend                                                   app/models/...
class Product < ActiveRecord::Base                 Modèleend                                                   app/models/...
class Product < ActiveRecord::Base                 Modèleend                                                   app/models/...
Que vient on de faire ?• Créer une classe product qui hérite de AR::Base  Model• Créer un contrôleur qui gère les actions ...
Le modèle avec      Active Record• S’interface avec la base de données• SQLite par défaut• Plus de SQL manuel• Plus de ris...
Créer un modèle
Créer un modèle$ ruby script/generate model Product name:string description:text price:floatcategory_id:integer
Créer un modèle$ ruby script/generate model Product name:string description:text price:floatcategory_id:integer  class Crea...
Configuration & log
Configuration & logconfig/database.yml    development:     adapter: sqlite3     database: db/        Adaptateurs pour MySQL,...
Configuration & logconfig/database.yml    development:     adapter: sqlite3     database: db/            Adaptateurs pour My...
Créer un produit
Créer un produitc = Category.firstProduct.create({   :name => "Ruby on Rails", # injection SQL   :description => "First boo...
Créer un produit   c = Category.first   Product.create({      :name => "Ruby on Rails", # injection SQL      :description =...
Encore trop complexe ?Besoin d’un outil qui gère le CRUD en 1 commande:  • Create  • Read  • Update  • Delete
Scaffold
Scaffold
Plus qu’une migration• Et vous pouvez: • Créer des produits (Create) • Les lister et afficher (Read) • Les mettre à jour (U...
En images
Les relations
Les relations class Category < ActiveRecord::Base   has_many :products                                       Une catégorie...
Les relations class Category < ActiveRecord::Base   has_many :products                                       Une catégorie...
Les relations class Category < ActiveRecord::Base   has_many :products                                       Une catégorie...
Les finder
Les finderProduct.find(:all, :conditions => { :price => 18 })Product.find(:first)Product.find(:last)
Les finder Product.find(:all, :conditions => { :price => 18 }) Product.find(:first) Product.find(:last)Plusieurs finder dynamiqu...
Les finder Product.find(:all, :conditions => { :price => 18 }) Product.find(:first) Product.find(:last)Plusieurs finder dynamiqu...
Les scope
Les scopeclass Product < ActiveRecord::Base     named_scope :recent, lambda { { :conditions => ["created_at > ?", 5.days.a...
Les scope class Product < ActiveRecord::Base      named_scope :recent, lambda { { :conditions => ["created_at > ?", 5.days...
Les validations  class Product < ActiveRecord::Base     belongs_to :category     validates_presence_of :name, :category_id...
Le contrôleur avec    ActionController• L’interface entre le modèle et la vue• Association automatique méthode / vue• @var...
Le routeurconfig/routes.rbActionController::Routing::Routes.draw do |map|  # RESTful /categories/1/products/1/  map.resourc...
Les routes rake routes   categories GET        /categories(.:format)        {:controller=>"categories", :action=>"index"} ...
Les contrôleursclass ProductsController < ApplicationController   before_filter :authenticate, :only => :index  def index  ...
La vue avec         ActionView• Les vues : pas forcément du HTML• Layout• Partials• Helpers
Les types de vuesi18n des vues app/views/products/index.fr.html.erb app/views/products/index.es.html.erb   Rails >= 2.3
Les types de vuesi18n des vues app/views/products/index.fr.html.erb app/views/products/index.es.html.erb   Rails >= 2.3Dif...
Le layoutSquelette de base   app/views/layouts/application.html.erbModifiable depuis    <!DOCTYPE…>                    <htm...
Les partialsDes morceaux de vue <!DOCTYPE…> <html> <body>                                         app/views/products/_side...
Exemple de vue: liste<h1>Listing categories</h1><table> <tr>  <th>Name</th> </tr><% @categories.each do |category| %> <tr>...
Exemple de vue: édition<% form_for(@product) do |f| %> <%= f.error_messages %> <p>  <%= f.label :name %><br />  <%= f.text...
Autour de Rails•   Communauté active     config/environment.rb•   Autour de github       Rails::Initializer.run do |config| ...
Documentation• http://www.rubyonrails.org/• http://guides.rubyonrails.org/• http://apidock.com/rails• http://railsforzombi...
Merci, c’est à vous !• Des questions ?    _fuse      mcatty@synbioz.com
Ruby on rails presentation
Upcoming SlideShare
Loading in...5
×

Ruby on rails presentation

1,035
-1

Published on

French presentation of ruby and ruby on rails for beginners.

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,035
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
24
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Ruby on rails presentation

    1. 1. Ruby on Rails Supinfo 2011
    2. 2. A propos• Martin Catty, fondateur de Synbioz• Rubyiste depuis 2006 _fuse mcatty@synbioz.com
    3. 3. Ruby avant Rails• Ne partez pas sans vos bagages !• Rails a aidé à l’essor de Ruby• Mais pas de framework sans langage
    4. 4. Ruby On ne va pas (ou peu) parler de: I/O Test VM ThreadImplémentations Debugger Garbage Proc / lambda Exceptions Réseau
    5. 5. L’Histoire• Créé par Yukihiro Matsumoto (Matz)• Release publique en 2005
    6. 6. Un langage• Plus objet que python• Plus puissant que perl• Fun
    7. 7. Les versions• Stable actuelle: 1.9.2• 1.8.7 dans la branche 1.8• 1.8.7 (p250) fonctionne avec Rails 2 et 3• < 1.8.7 = Rails 2• > 1.8.7 = Rails 3
    8. 8. Le fameux hello world Java Ruby
    9. 9. Le fameux hello world Java Rubyclass Hello { public static void main(String [] args) { system.out.println(‘Hello’); }}
    10. 10. Le fameux hello world Java Rubyclass Hello { public static void main(String [] args) { system.out.println(‘Hello’); puts ‘Hello’ }}
    11. 11. Le fameux hello world Java Rubyclass Hello { public static void main(String [] args) { system.out.println(‘Hello’); puts ‘Hello’ }} </troll>
    12. 12. Tout est objet
    13. 13. Tout est objet 2.times { puts "Bonjour Supinfo." }=> Bonjour Supinfo=> Bonjour Supinfo
    14. 14. Tout est objet 2.times { puts "Bonjour Supinfo." } 3.upto(5) { |i| puts i }=> Bonjour Supinfo => 3=> Bonjour Supinfo => 4 => 5
    15. 15. Tout est objet 2.times { puts "Bonjour Supinfo." } 3.upto(5) { |i| puts i }=> Bonjour Supinfo => 3=> Bonjour Supinfo => 4 => 5 p 1.zero?=> false
    16. 16. Tout est objet 2.times { puts "Bonjour Supinfo." } 3.upto(5) { |i| puts i }=> Bonjour Supinfo => 3=> Bonjour Supinfo => 4 => 5 p 1.zero? 39 + 3=> false => 39.+(3)
    17. 17. Les variablesclass A MAX = 42 A.new("a") @@instances = 0 A.new("b") def initialize(name) @name = name A.new("c") @@instances += 1 end A.new("d") def self.instances A.new("e") @@instances endend p A.instances #=> 5
    18. 18. Itérations
    19. 19. Itérationsa = 1..9for i in a puts iend
    20. 20. Itérations a = 1..9 for i in a puts i end=> 1…9
    21. 21. Itérations a = 1..9 for i in a puts i ou end=> 1…9
    22. 22. Itérations a = 1..9 for i in a a = 1..9 puts i ou a.each { |i| puts i } end=> 1…9
    23. 23. Itérations a = 1..9 for i in a a = 1..9 puts i ou a.each { |i| puts i } end=> 1…9 => 1…9
    24. 24. Itérations a = 1..9 for i in a a = 1..9 puts i ou a.each { |i| puts i } end=> 1…9 => 1…9 i=0 loop do i += 1 puts i break if 10 == i end
    25. 25. Itérations a = 1..9 for i in a a = 1..9 puts i ou a.each { |i| puts i } end=> 1…9 => 1…9 i=0 loop do i += 1 puts i break if 10 == i end=> 1…9
    26. 26. Itérations a = 1..9 for i in a a = 1..9 puts i ou a.each { |i| puts i } end=> 1…9 => 1…9 i=0 loop do i += 1 1.upto(10) do |i| puts i next if i.odd? # pas dimpair en ruby break if 10 == i puts i end end=> 1…9
    27. 27. Itérations a = 1..9 for i in a a = 1..9 puts i ou a.each { |i| puts i } end=> 1…9 => 1…9 i=0 loop do i += 1 1.upto(10) do |i| puts i next if i.odd? # pas dimpair en ruby break if 10 == i puts i end end=> 1…9 => 2, 4, 6, 8, 10
    28. 28. Itérations a = 1..9 for i in a a = 1..9 puts i ou a.each { |i| puts i } end=> 1…9 => 1…9 i=0 loop do i += 1 1.upto(10) do |i| puts i next if i.odd? # pas dimpair en ruby break if 10 == i puts i end end=> 1…9 => 2, 4, 6, 8, 10 1.upto(2) do |i| v = rand(2) retry if v.zero? end
    29. 29. Conditions
    30. 30. Conditionsif index == 1else puts ‘0’ if index.zero? puts ‘not 0’ unless index.zero?end
    31. 31. Conditionsif index == 1else puts ‘0’ if index.zero? puts ‘not 0’ unless index.zero?enddef what_is_it?(a) case a what_is_it?(1) when 1..2 # 1 or 2 puts "1 or 2" what_is_it?(2) when 3 # 1 or 2 puts "3" what_is_it?(3) when /4.*/ # Regexp #3 puts "something starting with 4." what_is_it?("4004") when "foo" # something starting with 4. puts "foo" what_is_it?("foo") else # foo puts "I dont know." what_is_it?(5) end # Dont know.end
    32. 32. Tableaux 1/21
    33. 33. Tableaux 1/21 lost = [8, 15, 16, 23] lost << 42 # push lost.unshift(4) # [4, 8, 15, 16, 23, 42]
    34. 34. Tableaux 1/21 lost = [8, 15, 16, 23] lost << 42 # push lost.unshift(4) # [4, 8, 15, 16, 23, 42]
    35. 35. Tableaux 1/21 lost = [8, 15, 16, 23] lost.at(0) lost << 42 # push #4 lost.unshift(4) lost[-1] # [4, 8, 15, 16, 23, 42] # 42
    36. 36. Tableaux 1/21 lost = [8, 15, 16, 23] lost.at(0) lost << 42 # push #4 lost.unshift(4) lost[-1] # [4, 8, 15, 16, 23, 42] # 42
    37. 37. Tableaux 1/21 lost = [8, 15, 16, 23] lost.at(0) lost << nil << nil lost << 42 # push #4 lost.unshift(4) lost[-1] # [4, 8, 15, 16, 23, 42, # [4, 8, 15, 16, 23, 42] # 42 nil, nil]
    38. 38. Tableaux 1/21 lost = [8, 15, 16, 23] lost.at(0) lost << nil << nil lost << 42 # push #4 lost.unshift(4) lost[-1] # [4, 8, 15, 16, 23, 42, # [4, 8, 15, 16, 23, 42] # 42 nil, nil]
    39. 39. Tableaux 1/21 lost = [8, 15, 16, 23] lost.at(0) lost << nil << nil lost << 42 # push #4 lost.unshift(4) lost[-1] # [4, 8, 15, 16, 23, 42, # [4, 8, 15, 16, 23, 42] # 42 nil, nil] lost.compact! # [4, 8, 15, 16, 23, 42]
    40. 40. Tableaux 1/21 lost = [8, 15, 16, 23] lost.at(0) lost << nil << nil lost << 42 # push #4 lost.unshift(4) lost[-1] # [4, 8, 15, 16, 23, 42, # [4, 8, 15, 16, 23, 42] # 42 nil, nil] lost.compact! # [4, 8, 15, 16, 23, 42]
    41. 41. Tableaux 1/21 lost = [8, 15, 16, 23] lost.at(0) lost << nil << nil lost << 42 # push #4 lost.unshift(4) lost[-1] # [4, 8, 15, 16, 23, 42, # [4, 8, 15, 16, 23, 42] # 42 nil, nil] lost << [4, 8] lost.compact! # [4, 8, 15, 16, 23, 42, # [4, 8, 15, 16, 23, 42] [4, 8]]
    42. 42. Tableaux 1/21 lost = [8, 15, 16, 23] lost.at(0) lost << nil << nil lost << 42 # push #4 lost.unshift(4) lost[-1] # [4, 8, 15, 16, 23, 42, # [4, 8, 15, 16, 23, 42] # 42 nil, nil] lost << [4, 8] lost.compact! # [4, 8, 15, 16, 23, 42, # [4, 8, 15, 16, 23, 42] [4, 8]]
    43. 43. Tableaux 1/21 lost = [8, 15, 16, 23] lost.at(0) lost << nil << nil lost << 42 # push #4 lost.unshift(4) lost[-1] # [4, 8, 15, 16, 23, 42, # [4, 8, 15, 16, 23, 42] # 42 nil, nil] lost.flatten!.uniq! lost << [4, 8] lost.compact! # [4, 8, 15, 16, 23, 42] # [4, 8, 15, 16, 23, 42, # [4, 8, 15, 16, 23, 42] [4, 8]]
    44. 44. Tableaux 1/21 lost = [8, 15, 16, 23] lost.at(0) lost << nil << nil lost << 42 # push #4 lost.unshift(4) lost[-1] # [4, 8, 15, 16, 23, 42, # [4, 8, 15, 16, 23, 42] # 42 nil, nil] lost.flatten!.uniq! lost << [4, 8] lost.compact! # [4, 8, 15, 16, 23, 42] # [4, 8, 15, 16, 23, 42, # [4, 8, 15, 16, 23, 42] [4, 8]] lost.index(23) #4
    45. 45. Tableaux 1/21 lost = [8, 15, 16, 23] lost.at(0) lost << nil << nil lost << 42 # push #4 lost.unshift(4) lost[-1] # [4, 8, 15, 16, 23, 42, # [4, 8, 15, 16, 23, 42] # 42 nil, nil] lost.flatten!.uniq! lost << [4, 8] lost.compact! # [4, 8, 15, 16, 23, 42] # [4, 8, 15, 16, 23, 42, # [4, 8, 15, 16, 23, 42] [4, 8]] lost.shuffle lost.index(23) # [16, 23, 42, 4, 15, 8] [5, 3, 7, 39, 1, 15].sort #4 # [1, 3, 5, 7, 15, 39]
    46. 46. Tableaux 1/21 lost = [8, 15, 16, 23] lost.at(0) lost << nil << nil lost << 42 # push #4 lost.unshift(4) lost[-1] # [4, 8, 15, 16, 23, 42, # [4, 8, 15, 16, 23, 42] # 42 nil, nil] lost.flatten!.uniq! lost << [4, 8] lost.compact! # [4, 8, 15, 16, 23, 42] # [4, 8, 15, 16, 23, 42, # [4, 8, 15, 16, 23, 42] [4, 8]] lost.shuffle lost.index(23) # [16, 23, 42, 4, 15, 8] (a..z).to_a [5, 3, 7, 39, 1, 15].sort ["a", "b", "c", "d"…] #4 # [1, 3, 5, 7, 15, 39]
    47. 47. Tableaux 2/2
    48. 48. Tableaux 2/2double_lost = lost.map { |v| v * 2 }# => [8, 16, 30, 32, 46, 84]
    49. 49. Tableaux 2/2 # lost: [4, 8, 15, 16, 23, 42]double_lost = lost.map { |v| v * 2 } double_lost - lost# => [8, 16, 30, 32, 46, 84] # => [30, 32, 46, 84]
    50. 50. Tableaux 2/2 # lost: [4, 8, 15, 16, 23, 42]double_lost = lost.map { |v| v * 2 } double_lost - lost# => [8, 16, 30, 32, 46, 84] # => [30, 32, 46, 84]# intersectiondouble_lost & lost# [8, 16]
    51. 51. Tableaux 2/2 # lost: [4, 8, 15, 16, 23, 42]double_lost = lost.map { |v| v * 2 } double_lost - lost# => [8, 16, 30, 32, 46, 84] # => [30, 32, 46, 84]# intersection # jointuredouble_lost & lost (double_lost | lost).sort# [8, 16] # [4, 8, 15, 16, 23, 30, 32, 42, 46, 84]
    52. 52. String
    53. 53. Stringstr = "bar"puts foo #{str}# => foo #{str}
    54. 54. Stringstr = "bar" # Interpolationputs foo #{str} puts "foo #{str}"# => foo #{str} # => foo bar
    55. 55. Stringstr = "bar" # Interpolationputs foo #{str} puts "foo #{str}"# => foo #{str} # => foo barstr = "a"str.succ# => "b"
    56. 56. Stringstr = "bar" # Interpolationputs foo #{str} puts "foo #{str}"# => foo #{str} # => foo barstr = "a" str = "foon"str.succ str.chomp# => "b" # => "foo"
    57. 57. Stringstr = "bar" # Interpolationputs foo #{str} puts "foo #{str}"# => foo #{str} # => foo barstr = "a" str = "foon"str.succ str.chomp# => "b" # => "foo"str = "foo"str.chop# => "fo"
    58. 58. Stringstr = "bar" # Interpolationputs foo #{str} puts "foo #{str}"# => foo #{str} # => foo barstr = "a" str = "foon"str.succ str.chomp# => "b" # => "foo" "supinfo".capitalizestr = "foo" # => "Supinfo"str.chop "supinfo".upcase# => "fo" # => "SUPINFO"
    59. 59. Stringstr = "bar" # Interpolationputs foo #{str} puts "foo #{str}" # attention, en 1.8# => foo #{str} # => foo bar str = "éhé" str.size # => 5 et non 3 str[0]str = "a" str = "foon" # 195 et non é (code ascii)str.succ str.chomp# => "b" # => "foo" # patché dans rails str.mb_chars[0] #é "supinfo".capitalize str.mb_chars.sizestr = "foo" #3 # => "Supinfo"str.chop "supinfo".upcase# => "fo" # => "SUPINFO"
    60. 60. HashAssociation clé / valeur
    61. 61. HashAssociation clé / valeur h = { :a => a, :b => 42, :c => { :d => f } } h2 = { :a => foo } h.merge(h2) => {:a=>"foo", :b=>42, :c=>{:d=>"f"}}
    62. 62. Class: les constructeurs
    63. 63. Class: les constructeursclass A def A.new endendA.new
    64. 64. Class: les constructeursclass A class B def A.new def self.new end endend endA.new B.new
    65. 65. Class: les constructeursclass A class B def A.new def self.new end endend endA.new B.newclass C def initialize endendC.new
    66. 66. Class: les constructeursclass A class B def A.new def self.new end endend endA.new B.new class D # pas de constructeur multipleclass C def initialize; end def initialize end def initialize(*args)end end endC.new D.new # => KO D.new(1) # => OK
    67. 67. Class: les accesseurs
    68. 68. Class: les accesseursclass Product def initialize(name, description, price) @name = name @description = description @price = price end def name @name end def name=(name) @name = name end …end
    69. 69. Class: les accesseursclass Product def initialize(name, description, price) @name = name @description = description class Product @price = price attr_accessor :name end attr_reader: description attr_writer :price def name @name def initialize(name, description, price) end @name = name @description = description def name=(name) @price = price @name = name end end end …end
    70. 70. Class: portée & héritage
    71. 71. Class: portée & héritageclass Animal def initialize puts "Born to be alive." end protected def breathe? puts "inhale, exhale" true end private def speak; endend# Animal.new.speak# => fail with private method `speak
    72. 72. Class: portée & héritageclass Animal class Dog < Animal def initialize def alive? puts "Born to be alive." puts "Im alive" if breathe? end end protected def speak def breathe? puts "woff." puts "inhale, exhale" end true end end snoopy = Dog.new private # Born to be alive. def speak; end snoopy.speakend # woff. snoopy.alive?# Animal.new.speak # inhale, exhale# => fail with private method `speak # Im alive
    73. 73. Class: étendre
    74. 74. Class: étendre# Etendre un objetstr = "foo"class << str def blank? self !~ /S/ endendstr.blank?# => false
    75. 75. Class: étendre# Etendre un objet # Etendre une classestr = "foo" class String def blank?class << str self !~ /S/ def blank? end self !~ /S/ end endend " ".blank? # => truestr.blank? "foo".blank?# => false # => false
    76. 76. Class: ce qui n’existe pas• Pas d’héritage multiple• Basé sur les mixins• Pas d’interface• Pas de classe abstraite native
    77. 77. Les outilsirb : votre shell ruby [17:59:57] fuse@h [~]$ irb ruby-1.8.7-p302 :001 > puts ‘foo’ foo => nil ruby-1.8.7-p302 :002 > 21 * 2 => 42 ruby-1.8.7-p302 :008 > String.methods.sort => ["<", "<=", "<=>", "==", "===", "=~", ">", …]rvm : gérer plusieurs versions de ruby
    78. 78. Documentation• http://www.ruby-doc.org/• http://www.ruby-lang.org/• http://apidock.com/ruby• Le pickAxe: LA référence• http://tryruby.org/• http://groups.google.com/group/rubyfr- public
    79. 79. RailsOn ne va pas (ou peu) parler de: Copieurs Test I18n Rake Cache Rails 3 ActionMailer Déploiement ActiveSupport
    80. 80. L’Histoire• Créé par DHH (David Heinemeier Hansson)• Version 1 en décembre 2005• Pragmatique dès le début: basecamp
    81. 81. Rails en entreprise• Plus un jouet• Présent en entreprise, grandes et petites• Opportunités en temps que développeur
    82. 82. Les versions• Stable actuelle: 3.0.7 • Rails 3 issue du merge avec merb (08/10) • Framework agnostic• Stable actuelle: 2.3.11 • La plus rencontrée en entreprise
    83. 83. Des conventionsQuelques noms barbares:• Convention over configuration• DRY• MVC
    84. 84. Convention over configuration• Votre passion est de customiser Tomcat ? Désolé !• 0 conf pour commencer à développer • Serveur web embarqué • BDD embarquée
    85. 85. Don’t repeat yourself• - de code = - de bug• - de code = - de maintenance• - de code = + de temps
    86. 86. Modèle - Vue - Contrôleur Modèle Contrôleur Vue Métier Fonctionnel Affichage
    87. 87. Rails en vrai• Pas de hello world, c’est trop simple…• La classique liste de produits plutôt.
    88. 88. Créons notre application $ rails app3 environnements
    89. 89. class Product < ActiveRecord::Base Modèleend app/models/product.rb
    90. 90. class Product < ActiveRecord::Base Modèleend app/models/product.rbclass ProductsController < ApplicationController Contrôleur def index @products = Product.all app/controllers/ end end products_controller.rb
    91. 91. class Product < ActiveRecord::Base Modèleend app/models/product.rbclass ProductsController < ApplicationController Contrôleur def index @products = Product.all app/controllers/ end end products_controller.rb <html><body> Vue <% for product in @products %> <p><%= product.name %></p> app/views/products/ <% end %> </body></html> index.html.erb
    92. 92. class Product < ActiveRecord::Base Modèleend app/models/product.rbclass ProductsController < ApplicationController Contrôleur def index @products = Product.all app/controllers/ end end products_controller.rb <html><body> Vue <% for product in @products %> <p><%= product.name %></p> app/views/products/ <% end %> </body></html> index.html.erb
    93. 93. Que vient on de faire ?• Créer une classe product qui hérite de AR::Base Model• Créer un contrôleur qui gère les actions (ex: index) Contrôleur• Créer des vues pour afficher la liste et les formulaires Vue
    94. 94. Le modèle avec Active Record• S’interface avec la base de données• SQLite par défaut• Plus de SQL manuel• Plus de risque d’injections
    95. 95. Créer un modèle
    96. 96. Créer un modèle$ ruby script/generate model Product name:string description:text price:floatcategory_id:integer
    97. 97. Créer un modèle$ ruby script/generate model Product name:string description:text price:floatcategory_id:integer class CreateProducts < ActiveRecord::Migration def self.up create_table :products do |t| db/migrate/ t.string :name t.text :description 20110322113407_ t.float :price create_products.rb t.integer :category_id t.timestamps end rake db:migrate end def self.down drop_table :products end end
    98. 98. Configuration & log
    99. 99. Configuration & logconfig/database.yml development: adapter: sqlite3 database: db/ Adaptateurs pour MySQL, development.sqlite3 pool: 5 Postgresql, oracle… timeout: 5000
    100. 100. Configuration & logconfig/database.yml development: adapter: sqlite3 database: db/ Adaptateurs pour MySQL, development.sqlite3 pool: 5 Postgresql, oracle… timeout: 5000Dans le contrôleur log/development.log Product Load (0.3ms) @products = Product.all SELECT * FROM "products"
    101. 101. Créer un produit
    102. 102. Créer un produitc = Category.firstProduct.create({ :name => "Ruby on Rails", # injection SQL :description => "First book on RoR", :price => 10.0, :category => c })
    103. 103. Créer un produit c = Category.first Product.create({ :name => "Ruby on Rails", # injection SQL :description => "First book on RoR", :price => 10.0, :category => c })log/development.log Product Create (0.8ms) INSERT INTO "products"("name", "price", "created_at", "updated_at", "category_id", "description")VALUES(Ruby on Rails, 10.0, 2011-03-22 18:13:07, 2011-03-22 18:13:07, 1, Firstbook on RoR)
    104. 104. Encore trop complexe ?Besoin d’un outil qui gère le CRUD en 1 commande: • Create • Read • Update • Delete
    105. 105. Scaffold
    106. 106. Scaffold
    107. 107. Plus qu’une migration• Et vous pouvez: • Créer des produits (Create) • Les lister et afficher (Read) • Les mettre à jour (Update) • Et les supprimer (Delete)
    108. 108. En images
    109. 109. Les relations
    110. 110. Les relations class Category < ActiveRecord::Base has_many :products Une catégorie possèdeend n produits
    111. 111. Les relations class Category < ActiveRecord::Base has_many :products Une catégorie possèdeend n produits class Product < ActiveRecord::Base Un produit appartient à belongs_to :categoryend une catégorie
    112. 112. Les relations class Category < ActiveRecord::Base has_many :products Une catégorie possèdeend n produits class Product < ActiveRecord::Base Un produit appartient à belongs_to :categoryend une catégorieou class Product < ActiveRecord::Base Une catégorie possède has_and_belongs_to_many :category n produits et unend produit n catégories
    113. 113. Les finder
    114. 114. Les finderProduct.find(:all, :conditions => { :price => 18 })Product.find(:first)Product.find(:last)
    115. 115. Les finder Product.find(:all, :conditions => { :price => 18 }) Product.find(:first) Product.find(:last)Plusieurs finder dynamiques: Product.find_by_name(‘rails’) Product.find_all_by_name(‘rails’) Product.find_by_name_and_price(‘book’, 18)
    116. 116. Les finder Product.find(:all, :conditions => { :price => 18 }) Product.find(:first) Product.find(:last)Plusieurs finder dynamiques: Product.find_by_name(‘rails’) Product.find_all_by_name(‘rails’) Product.find_by_name_and_price(‘book’, 18)Jointure: Product.find(:all, :joins => :category, :conditions => { :categories => { :name => "books" }})
    117. 117. Les scope
    118. 118. Les scopeclass Product < ActiveRecord::Base named_scope :recent, lambda { { :conditions => ["created_at > ?", 5.days.ago] } } named_scope :limit, lambda { |n| { :limit => n } } named_scope :ordered_by_name, { :order => "NAME ASC" } end
    119. 119. Les scope class Product < ActiveRecord::Base named_scope :recent, lambda { { :conditions => ["created_at > ?", 5.days.ago] } } named_scope :limit, lambda { |n| { :limit => n } } named_scope :ordered_by_name, { :order => "NAME ASC" } endInvoquer les scope, de façon chaînable Product.recent.ordered_by_name.limit(2) Product Load (0.3ms) SELECT * FROM "products" WHERE (created_at > 2011-03-17 21:08:24) ORDER BY NAME ASC LIMIT 2
    120. 120. Les validations class Product < ActiveRecord::Base belongs_to :category validates_presence_of :name, :category_id validates_numericality_of :priceet bien d’autres:validates_confirmation_ofvalidates_exclusion_ofvalidates_format_ofvalidates_inclusion_ofvalidates_length_of…
    121. 121. Le contrôleur avec ActionController• L’interface entre le modèle et la vue• Association automatique méthode / vue• @variable directement disponible dans la vue• Possibilité de filtrer des actions
    122. 122. Le routeurconfig/routes.rbActionController::Routing::Routes.draw do |map| # RESTful /categories/1/products/1/ map.resources :categories do |category| category.resources :products end # route nommée map.purchase products/:id/purchase, :controller => catalog, :action => purchase # namespace map.namespace :admin do |admin| # /admin/products admin.resource :products end # route par défaut map.root :controller => productsend
    123. 123. Les routes rake routes categories GET /categories(.:format) {:controller=>"categories", :action=>"index"} POST /categories(.:format) {:controller=>"categories", :action=>"create"} new_category GET /categories/new(.:format) {:controller=>"categories", :action=>"new"}edit_category GET /categories/:id/edit(.:format) {:controller=>"categories", :action=>"edit"} category GET /categories/:id(.:format) {:controller=>"categories", :action=>"show"} PUT /categories/:id(.:format) {:controller=>"categories", :action=>"update"} DELETE /categories/:id(.:format) {:controller=>"categories", :action=>"destroy"} products GET /products(.:format) {:controller=>"products", :action=>"index"} POST /products(.:format) {:controller=>"products", :action=>"create"} new_product GET /products/new(.:format) {:controller=>"products", :action=>"new"} edit_product GET /products/:id/edit(.:format) {:controller=>"products", :action=>"edit"} product GET /products/:id(.:format) {:controller=>"products", :action=>"show"} PUT /products/:id(.:format) {:controller=>"products", :action=>"update"} DELETE /products/:id(.:format) {:controller=>"products", :action=>"destroy"} /:controller/:action/:id /:controller/:action/:id(.:format) root / {:controller=>"products", :action=>"index"}
    124. 124. Les contrôleursclass ProductsController < ApplicationController before_filter :authenticate, :only => :index def index @products = Product.all #disponible dans la vue respond_to do |format| # GET /products format.html # index.html.erb # GET /products.xml format.xml { render :xml => @products } end end private def authenticate # do some stuff endend
    125. 125. La vue avec ActionView• Les vues : pas forcément du HTML• Layout• Partials• Helpers
    126. 126. Les types de vuesi18n des vues app/views/products/index.fr.html.erb app/views/products/index.es.html.erb Rails >= 2.3
    127. 127. Les types de vuesi18n des vues app/views/products/index.fr.html.erb app/views/products/index.es.html.erb Rails >= 2.3Différents formats app/views/products/index.iphone.erb app/views/products/index.xml.erb
    128. 128. Le layoutSquelette de base app/views/layouts/application.html.erbModifiable depuis <!DOCTYPE…> <html>le contrôleur <body> <%= yield %> </body> </html>
    129. 129. Les partialsDes morceaux de vue <!DOCTYPE…> <html> <body> app/views/products/_sidebar.html.erb <%= render :partial => ‘products/sidebar’ %> <%= yield %> </body> </html>
    130. 130. Exemple de vue: liste<h1>Listing categories</h1><table> <tr> <th>Name</th> </tr><% @categories.each do |category| %> <tr> <td><%=h truncate(category.name, :size => 10) %></td> <td><%= link_to Show, category %></td> <td><%= link_to Edit, edit_category_path(category) %></td> <td><%= link_to Destroy, category, :confirm => Are you sure?, :method=> :delete %></td> </tr><% end %></table><br /><%= link_to New category, new_category_path %>
    131. 131. Exemple de vue: édition<% form_for(@product) do |f| %> <%= f.error_messages %> <p> <%= f.label :name %><br /> <%= f.text_field :name %> </p><p> <%= f.label :description %><br /> <%= f.text_area :description %> </p><p> <%= f.label :available %><br /> <%= f.check_box :available %> </p><p> <%= f.label :category_id %><br /> <%= f.select :category_id, (Category.all.map do |c| [c.name, c.id] end) %> </p><p> <%= f.submit Update %> </p><% end %><%= link_to Show, @product %> |<%= link_to Back, products_path %>
    132. 132. Autour de Rails• Communauté active config/environment.rb• Autour de github Rails::Initializer.run do |config| config.gem ‘hpricot’• end Gems • Authentification • Pagination • …
    133. 133. Documentation• http://www.rubyonrails.org/• http://guides.rubyonrails.org/• http://apidock.com/rails• http://railsforzombies.org/• http://groups.google.com/group/railsfrance
    134. 134. Merci, c’est à vous !• Des questions ? _fuse mcatty@synbioz.com
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×