ruby on rails supinfo 2011. a propos martin catty, fondateur de synbioz rubyiste depuis 2006 _fuse...

60
Ruby on Rails Supinfo 2011

Upload: molly-chase

Post on 26-Mar-2015

214 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Ruby on RailsSupinfo 2011

Page 2: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

A propos

•Martin Catty, fondateur de Synbioz

•Rubyiste depuis 2006

_fuse [email protected]

Page 3: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Ruby avant Rails

•Ne partez pas sans vos bagages !

•Rails a aidé à l’essor de Ruby

•Mais pas de framework sans langage

Page 4: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

RubyOn ne va pas (ou peu) parler de:

I/O

Réseau

ThreadTest

Debugger

Proc / lambda Exceptions

Garbage

VM

Implémentations

Page 5: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

L’Histoire

•Créé par Yukihiro Matsumoto (Matz)

•Release publique en 2005

Page 6: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Un langage

•Plus objet que python

•Plus puissant que perl

•Fun

Page 7: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

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

Page 8: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Le fameux hello world

classclass Hello { Hello {public static void main(String [] public static void main(String [] args) {args) {

system.out.println(‘Hello’);system.out.println(‘Hello’);}}

}}

classclass Hello { Hello {public static void main(String [] public static void main(String [] args) {args) {

system.out.println(‘Hello’);system.out.println(‘Hello’);}}

}}

Java Ruby

putsputs ‘Hello’ ‘Hello’putsputs ‘Hello’ ‘Hello’

</troll>

Page 9: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Tout est objet2.2.timestimes { puts "Bonjour { puts "Bonjour Supinfo." }Supinfo." }2.2.timestimes { puts "Bonjour { puts "Bonjour Supinfo." }Supinfo." }

=> Bonjour Supinfo

=> Bonjour Supinfo

3.3.uptoupto(5) { |i| puts i }(5) { |i| puts i }3.3.uptoupto(5) { |i| puts i }(5) { |i| puts i }

=> 3

=> 4

=> 5

p 1.p 1.zero?zero?p 1.p 1.zero?zero?

=> false

39 + 339 + 339 + 339 + 3

=> 39.+(3)

Page 10: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Les variablesclass Aclass A

MAXMAX = 42 = 42@@instances@@instances = 0 = 0def initialize(name)def initialize(name)

@name@name = = namename@@instances@@instances += 1 += 1

endend

def self.instancesdef self.instances@@instances@@instances

endendendend

class Aclass AMAXMAX = 42 = 42@@instances@@instances = 0 = 0def initialize(name)def initialize(name)

@name@name = = namename@@instances@@instances += 1 += 1

endend

def self.instancesdef self.instances@@instances@@instances

endendendend

A.new("a")A.new("b")A.new("c")A.new("d")A.new("e")

p A.instances #=> 5

Page 11: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Itérationsa = 1..9a = 1..9forfor i in a i in a

putsputs i iendend

a = 1..9a = 1..9forfor i in a i in a

putsputs i iendend

a = 1..9a = 1..9a.a.eacheach { |i| { |i| putsputs i } i }a = 1..9a = 1..9a.a.eacheach { |i| { |i| putsputs i } i }

=> 1…9

ou

i = 0i = 0looploop do i += 1 puts i do i += 1 puts i breakbreak if 10 == iend if 10 == iendi = 0i = 0looploop do i += 1 puts i do i += 1 puts i breakbreak if 10 == iend if 10 == iend

1.1.uptoupto(10) do |i| (10) do |i| nextnext if i.odd? if i.odd? # pas d'impair en ruby puts # pas d'impair en ruby puts iendiend

1.1.uptoupto(10) do |i| (10) do |i| nextnext if i.odd? if i.odd? # pas d'impair en ruby puts # pas d'impair en ruby puts iendiend

=> 2, 4, 6, 8, 10

=> 1…9

=> 1…9

1.upto(2) do |i| v = rand(2) 1.upto(2) do |i| v = rand(2) retryretry if v.zero?end if v.zero?end1.upto(2) do |i| v = rand(2) 1.upto(2) do |i| v = rand(2) retryretry if v.zero?end if v.zero?end

Page 12: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Conditionsifif index == 1 index == 1elseelseendend

ifif index == 1 index == 1elseelseendend

puts ‘0’ puts ‘0’ ifif index.zero?index.zero?puts ‘0’ puts ‘0’ ifif index.zero?index.zero?

puts ‘not 0’ puts ‘not 0’ unlessunless index.zero?index.zero?puts ‘not 0’ puts ‘not 0’ unlessunless index.zero?index.zero?

def what_is_it?(a) def what_is_it?(a) casecase a a whenwhen 1..2 1..2 puts "1 or 2" puts "1 or 2" whenwhen 3 puts "3" 3 puts "3" whenwhen /4.*/ # Regexp puts "something /4.*/ # Regexp puts "something starting with 4." starting with 4." whenwhen "foo" puts "foo" puts "foo" "foo" elseelse puts "I don't know." puts "I don't know." endendendend

def what_is_it?(a) def what_is_it?(a) casecase a a whenwhen 1..2 1..2 puts "1 or 2" puts "1 or 2" whenwhen 3 puts "3" 3 puts "3" whenwhen /4.*/ # Regexp puts "something /4.*/ # Regexp puts "something starting with 4." starting with 4." whenwhen "foo" puts "foo" puts "foo" "foo" elseelse puts "I don't know." puts "I don't know." endendendend

what_is_it?(1)# 1 or 2what_is_it?(2)# 1 or 2what_is_it?(3)# 3what_is_it?("4004")# something starting with 4.what_is_it?("foo")# foowhat_is_it?(5)# Don't know.

Page 13: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Tableaux 1/2lost = [8, 15, 16, lost = [8, 15, 16, 23]23]lost lost <<<< 42 # 42 # pushpushlost.lost.unshiftunshift(4)(4)# [4, 8, 15, 16, # [4, 8, 15, 16, 23, 42]23, 42]

lost = [8, 15, 16, lost = [8, 15, 16, 23]23]lost lost <<<< 42 # 42 # pushpushlost.lost.unshiftunshift(4)(4)# [4, 8, 15, 16, # [4, 8, 15, 16, 23, 42]23, 42]

lost lost <<<< nil nil <<<< nilnil

# [4, 8, 15, 16, # [4, 8, 15, 16, 23, 42, nil, nil]23, 42, nil, nil]

lost lost <<<< nil nil <<<< nilnil

# [4, 8, 15, 16, # [4, 8, 15, 16, 23, 42, nil, nil]23, 42, nil, nil]

lost.lost.compact!compact!

# [4, 8, 15, 16, # [4, 8, 15, 16, 23, 42]23, 42]

lost.lost.compact!compact!

# [4, 8, 15, 16, # [4, 8, 15, 16, 23, 42]23, 42]

lost lost <<<< [4, 8] [4, 8]

# [4, 8, 15, 16, # [4, 8, 15, 16, 23, 42, [4, 8]]23, 42, [4, 8]]

lost lost <<<< [4, 8] [4, 8]

# [4, 8, 15, 16, # [4, 8, 15, 16, 23, 42, [4, 8]]23, 42, [4, 8]]

lost.lost.flatten!flatten!..uniq!uniq!

# [4, 8, 15, 16, # [4, 8, 15, 16, 23, 42]23, 42]

lost.lost.flatten!flatten!..uniq!uniq!

# [4, 8, 15, 16, # [4, 8, 15, 16, 23, 42]23, 42]

lost.lost.indexindex(23)(23)

# 4# 4

lost.lost.indexindex(23)(23)

# 4# 4

lost.lost.shuffleshuffle# [16, 23, 42, 4, # [16, 23, 42, 4, 15, 8]15, 8][5, 3, 7, 39, 1, [5, 3, 7, 39, 1, 15].15].sortsort# [1, 3, 5, 7, 15, # [1, 3, 5, 7, 15, 39]39]

lost.lost.shuffleshuffle# [16, 23, 42, 4, # [16, 23, 42, 4, 15, 8]15, 8][5, 3, 7, 39, 1, [5, 3, 7, 39, 1, 15].15].sortsort# [1, 3, 5, 7, 15, # [1, 3, 5, 7, 15, 39]39]

('a'..'z').('a'..'z').to_ato_a["a", "b", "c", ["a", "b", "c", "d"…]"d"…]

('a'..'z').('a'..'z').to_ato_a["a", "b", "c", ["a", "b", "c", "d"…]"d"…]

lost.lost.atat(0)(0)# 4# 4lost[-1]lost[-1]# 42# 42

lost.lost.atat(0)(0)# 4# 4lost[-1]lost[-1]# 42# 42

1111

Page 14: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Tableaux 2/2double_lost = lost.double_lost = lost.mapmap { |v| v * { |v| v * 2 }2 }# => [8, 16, 30, 32, 46, 84]# => [8, 16, 30, 32, 46, 84]

double_lost = lost.double_lost = lost.mapmap { |v| v * { |v| v * 2 }2 }# => [8, 16, 30, 32, 46, 84]# => [8, 16, 30, 32, 46, 84]

# lost: [4, 8, 15, 16, 23, 42]# lost: [4, 8, 15, 16, 23, 42]double_lost double_lost -- lost lost# => [30, 32, 46, 84]# => [30, 32, 46, 84]

# lost: [4, 8, 15, 16, 23, 42]# lost: [4, 8, 15, 16, 23, 42]double_lost double_lost -- lost lost# => [30, 32, 46, 84]# => [30, 32, 46, 84]

# intersection# intersectiondouble_lost double_lost && lost lost# [8, 16]# [8, 16]

# intersection# intersectiondouble_lost double_lost && lost lost# [8, 16]# [8, 16]

# jointure# jointure(double_lost (double_lost || lost).sort lost).sort# [4, 8, 15, 16, 23, 30, 32, 42, # [4, 8, 15, 16, 23, 30, 32, 42, 46, 84]46, 84]

# jointure# jointure(double_lost (double_lost || lost).sort lost).sort# [4, 8, 15, 16, 23, 30, 32, 42, # [4, 8, 15, 16, 23, 30, 32, 42, 46, 84]46, 84]

Page 15: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

String

str = str = "a"str."a"str.succsucc# => # => "b""b"

str = str = "a"str."a"str.succsucc# => # => "b""b"

# # InterpolationInterpolationputsputs "foo "foo #{#{strstr}}""# # => foo bar=> foo bar

# # InterpolationInterpolationputsputs "foo "foo #{#{strstr}}""# # => foo bar=> foo bar

# attention, en 1.8# attention, en 1.8str = "éhé"str = "éhé"str.sizestr.size# => 5 et non # => 5 et non 33str[0]str[0]# 195 et non é # 195 et non é (code ascii)(code ascii)

# patché dans rails# patché dans railsstr.str.mb_charsmb_chars[0][0]# é # é str.mb_chars.sizestr.mb_chars.size# 3# 3

# attention, en 1.8# attention, en 1.8str = "éhé"str = "éhé"str.sizestr.size# => 5 et non # => 5 et non 33str[0]str[0]# 195 et non é # 195 et non é (code ascii)(code ascii)

# patché dans rails# patché dans railsstr.str.mb_charsmb_chars[0][0]# é # é str.mb_chars.sizestr.mb_chars.size# 3# 3

str = "bar"str = "bar"putsputs 'foo 'foo #{str}'#{str}'# => foo # => foo #{str}#{str}

str = "bar"str = "bar"putsputs 'foo 'foo #{str}'#{str}'# => foo # => foo #{str}#{str}

str = "foo\str = "foo\n"str.n"str.chompchomp# # => "foo"=> "foo"

str = "foo\str = "foo\n"str.n"str.chompchomp# # => "foo"=> "foo"

str = str = "foo"str."foo"str.chopchop# # => "fo"=> "fo"

str = str = "foo"str."foo"str.chopchop# # => "fo"=> "fo"

"supinfo"."supinfo".capitalicapitalizeze# => "Supinfo"# => "Supinfo""supinfo"."supinfo".upcaseupcase# => "SUPINFO"# => "SUPINFO"

"supinfo"."supinfo".capitalicapitalizeze# => "Supinfo"# => "Supinfo""supinfo"."supinfo".upcaseupcase# => "SUPINFO"# => "SUPINFO"

Page 16: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Hash

h = { :a => 'a', :b => 42, :c => { h = { :a => 'a', :b => 42, :c => { :d => 'f' } }:d => 'f' } }h = { :a => 'a', :b => 42, :c => { h = { :a => 'a', :b => 42, :c => { :d => 'f' } }:d => 'f' } }

h2 = { :a => 'foo' }h2 = { :a => 'foo' }h.h.mergemerge(h2)(h2)=> => {:a=>"foo", :b=>42, :c=>{:d=>"{:a=>"foo", :b=>42, :c=>{:d=>"f"}}f"}}

h2 = { :a => 'foo' }h2 = { :a => 'foo' }h.h.mergemerge(h2)(h2)=> => {:a=>"foo", :b=>42, :c=>{:d=>"{:a=>"foo", :b=>42, :c=>{:d=>"f"}}f"}}

Association clé / valeur

Page 17: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Class: les constructeurs

classclass A def A.new A def A.new endendendendA.newA.newclassclass A def A.new A def A.new endendendendA.newA.new

classclass B def self.new B def self.new endendendend

B.newB.new

classclass B def self.new B def self.new endendendend

B.newB.new

classclass C def C def initializeinitialize endendendendC.newC.newclassclass C def C def initializeinitialize endendendendC.newC.new

class D # pas de class D # pas de constructeur multiple def constructeur multiple def initializeinitialize; end def ; end def initializeinitialize(*args) endend(*args) endendD.new # => KOD.new(1) D.new # => KOD.new(1) # => OK# => OK

class D # pas de class D # pas de constructeur multiple def constructeur multiple def initializeinitialize; end def ; end def initializeinitialize(*args) endend(*args) endendD.new # => KOD.new(1) D.new # => KOD.new(1) # => OK# => OK

Page 18: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Class: les accesseurs

classclass Product Productdef def initializeinitialize(name, (name, description, price)description, price)

@name = name@name = name@description = description@description = description@price = price@price = price

endend

def namedef name@name@name

endend

def name=(name)def name=(name)@name = name@name = name

endend……

endend

classclass Product Productdef def initializeinitialize(name, (name, description, price)description, price)

@name = name@name = name@description = description@description = description@price = price@price = price

endend

def namedef name@name@name

endend

def name=(name)def name=(name)@name = name@name = name

endend……

endend

classclass Product Productattr_accessorattr_accessor :name :nameattr_readerattr_reader: description: descriptionattr_writerattr_writer :price :price

def def initializeinitialize(name, (name, description, price)description, price)

@name = name@name = name@description = description@description = description@price = price@price = price

endendendend

classclass Product Productattr_accessorattr_accessor :name :nameattr_readerattr_reader: description: descriptionattr_writerattr_writer :price :price

def def initializeinitialize(name, (name, description, price)description, price)

@name = name@name = name@description = description@description = description@price = price@price = price

endendendend

Page 19: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Class: portée & héritage

classclass Animal def Animal def initializeinitialize puts puts "Born to be alive." end "Born to be alive." end protectedprotected def breathe? puts def breathe? puts "inhale, exhale" "inhale, exhale" truetrue end end privateprivate def speak; end def speak; endendend

# Animal.new.speak # Animal.new.speak # => fail with private method # => fail with private method `speak'`speak'

classclass Animal def Animal def initializeinitialize puts puts "Born to be alive." end "Born to be alive." end protectedprotected def breathe? puts def breathe? puts "inhale, exhale" "inhale, exhale" truetrue end end privateprivate def speak; end def speak; endendend

# Animal.new.speak # Animal.new.speak # => fail with private method # => fail with private method `speak'`speak'

classclass Dog < Animal def Dog < Animal def alive?alive? puts "I'm alive" if breathe? end puts "I'm alive" if breathe? end def def speakspeak puts "woff." endend puts "woff." endend

snoopy = Dog.newsnoopy = Dog.new# Born to be alive.# Born to be alive.snoopy.speaksnoopy.speak# woff.# woff.snoopy.alive?snoopy.alive?# inhale, exhale# I'm alive# inhale, exhale# I'm alive

classclass Dog < Animal def Dog < Animal def alive?alive? puts "I'm alive" if breathe? end puts "I'm alive" if breathe? end def def speakspeak puts "woff." endend puts "woff." endend

snoopy = Dog.newsnoopy = Dog.new# Born to be alive.# Born to be alive.snoopy.speaksnoopy.speak# woff.# woff.snoopy.alive?snoopy.alive?# inhale, exhale# I'm alive# inhale, exhale# I'm alive

Page 20: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Class: étendre

# Etendre un objetstr = "foo"class << str def blank? self !~ /\S/ endendstr.blank?# => false# Etendre un objetstr = "foo"class << str def blank? self !~ /\S/ endendstr.blank?# => false

# Etendre une classe# Etendre une classeclassclass String String defdef blank? self ! blank? self !~ /\S/ ~ /\S/ endendendend" ".blank?" ".blank?# # => true=> true"foo".blank?"foo".blank?# => false# => false

# Etendre une classe# Etendre une classeclassclass String String defdef blank? self ! blank? self !~ /\S/ ~ /\S/ endendendend" ".blank?" ".blank?# # => true=> true"foo".blank?"foo".blank?# => false# => false

Page 21: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Class: ce qui n’existe pas

•Pas d’héritage multiple

•Basé sur les mixins

•Pas d’interface

•Pas de classe abstraite native

Page 22: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Les outils

[17:59:57] fuse@h [~]$ irb[17:59:57] fuse@h [~]$ irbruby-1.8.7-ruby-1.8.7-p302 :001 >p302 :001 > puts ‘foo’ puts ‘foo’foo => nilfoo => nilruby-1.8.7-p302 :002 >ruby-1.8.7-p302 :002 > 21 * 2 => 42 21 * 2 => 42ruby-1.8.7-p302 :008 >ruby-1.8.7-p302 :008 > String.methods.sort => ["<", "<=", String.methods.sort => ["<", "<=", "<=>", "==", "===", "=~", ">", …]"<=>", "==", "===", "=~", ">", …]

[17:59:57] fuse@h [~]$ irb[17:59:57] fuse@h [~]$ irbruby-1.8.7-ruby-1.8.7-p302 :001 >p302 :001 > puts ‘foo’ puts ‘foo’foo => nilfoo => nilruby-1.8.7-p302 :002 >ruby-1.8.7-p302 :002 > 21 * 2 => 42 21 * 2 => 42ruby-1.8.7-p302 :008 >ruby-1.8.7-p302 :008 > String.methods.sort => ["<", "<=", String.methods.sort => ["<", "<=", "<=>", "==", "===", "=~", ">", …]"<=>", "==", "===", "=~", ">", …]

irb : votre shell ruby

rvm : gérer plusieurs versions de ruby

Page 23: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

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

Page 24: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

RailsOn ne va pas (ou peu) parler de:

Test

CacheRake

ActionMailer

ActiveSupport

I18n

Déploiement

Copieurs

Rails 3

Page 25: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

L’Histoire

•Créé par DHH (David Heinemeier Hansson)

•Version 1 en décembre 2005

•Pragmatique dès le début: basecamp

Page 26: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Rails en entreprise

•Plus un jouet

•Présent en entreprise, grandes et petites

•Opportunités en temps que développeur

Page 27: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

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

Page 28: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Des conventions

•Convention over configuration

•DRY

•MVC

Quelques noms barbares:

Page 29: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Convention over configuration

•Votre passion est de customiser Tomcat ?Désolé !

•0 conf pour commencer à développer

•Serveur web embarqué

•BDD embarquée

Page 30: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Don’t repeat yourself

•- de code = - de bug

•- de code = - de maintenance

•- de code = + de temps

Page 31: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Modèle - Vue - Contrôleur

ContrôlContrôleureur

ContrôlContrôleureurModèleModèleModèleModèle VueVueVueVueContrôlContrôleureur

ContrôlContrôleureur

Métier Fonctionnel Affichage

Page 32: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Rails en vrai

•Pas de hello world, c’est trop simple…

•La classique liste de produits plutôt.

Page 33: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Créons notre application

$ rails app$ rails app$ rails app$ rails app

3 environnements

Page 34: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

class class ProductProduct < ActiveRecord::Base < ActiveRecord::Baseendendclass class ProductProduct < ActiveRecord::Base < ActiveRecord::Baseendend

Modèleapp/models/product.rb

class class ProductsControllerProductsController < < ApplicationControllerApplicationController

def indexdef index@products@products = = ProductProduct.all.all

endendendend

class class ProductsControllerProductsController < < ApplicationControllerApplicationController

def indexdef index@products@products = = ProductProduct.all.all

endendendend

Contrôleurapp/controllers/products_controller.rb

<html><body><html><body><% for product in <% for product in @products@products %> %><p><%= product.name %></p><p><%= product.name %></p><% end %><% end %></body></html></body></html>

<html><body><html><body><% for product in <% for product in @products@products %> %><p><%= product.name %></p><p><%= product.name %></p><% end %><% end %></body></html></body></html>

Vueapp/views/products/index.html.erb

Page 35: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Que vient on de faire ?

•Créer une classe product qui hérite de AR::Base

•Créer un contrôleur qui gère les actions (ex: index)

•Créer des vues pour afficher la liste et les formulaires

Model

Contrôleur

Vue

Page 36: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

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

Page 37: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Créer un modèle$ ruby $ ruby script/generatescript/generate model Product name: model Product name:stringstring description: description:texttext price:price:floatfloat category_id:category_id:integerinteger$ ruby $ ruby script/generatescript/generate model Product name: model Product name:stringstring description: description:texttext price:price:floatfloat category_id:category_id:integerinteger

classclass CreateProducts < CreateProducts < ActiveRecord::Migration def self.up ActiveRecord::Migration def self.up create_tablecreate_table :products do |t| :products do |t| t.string :name t.text :description t.string :name t.text :description t.float :price t.integer :category_id t.float :price t.integer :category_id t.timestamps end end def self.down t.timestamps end end def self.down drop_tabledrop_table :products endend :products endend

classclass CreateProducts < CreateProducts < ActiveRecord::Migration def self.up ActiveRecord::Migration def self.up create_tablecreate_table :products do |t| :products do |t| t.string :name t.text :description t.string :name t.text :description t.float :price t.integer :category_id t.float :price t.integer :category_id t.timestamps end end def self.down t.timestamps end end def self.down drop_tabledrop_table :products endend :products endend

db/migrate/20110322113407_create_products.rb

rake db:migrate

Page 38: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Configuration & log

@products@products = = ProductProduct.all.all@products@products = = ProductProduct.all.all

Dans le contrôleurlog/development.log

Product Load (0.3ms) Product Load (0.3ms) SELECT * FROM SELECT * FROM "products""products"

Product Load (0.3ms) Product Load (0.3ms) SELECT * FROM SELECT * FROM "products""products"

config/database.yml

development: adapter: development: adapter: sqlite3 database: sqlite3 database: db/development.sqlite3 db/development.sqlite3 pool: 5 timeout: 5000pool: 5 timeout: 5000

development: adapter: development: adapter: sqlite3 database: sqlite3 database: db/development.sqlite3 db/development.sqlite3 pool: 5 timeout: 5000pool: 5 timeout: 5000

Adaptateurs pour MySQL, Postgresql, oracle…

Page 39: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Créer un produit

c = Category.firstc = Category.firstProduct.Product.createcreate({ ({

:name => "Ruby 'on Rails", # injection SQL:name => "Ruby 'on Rails", # injection SQL:description => "First book on RoR", :description => "First book on RoR", :price => 10.0, :price => 10.0, :category => c }):category => c })

c = Category.firstc = Category.firstProduct.Product.createcreate({ ({

:name => "Ruby 'on Rails", # injection SQL:name => "Ruby 'on Rails", # injection SQL:description => "First book on RoR", :description => "First book on RoR", :price => 10.0, :price => 10.0, :category => c }):category => c })

Product Create (0.8ms)Product Create (0.8ms) INSERT INTO "products" INSERT INTO "products" ("name", "price", "created_at", "updated_at", "category_id", ("name", "price", "created_at", "updated_at", "category_id", "description") VALUES"description") VALUES('Ruby ''on Rails', 10.0, '2011-03-22 18:13:07', '2011-03-22 ('Ruby ''on Rails', 10.0, '2011-03-22 18:13:07', '2011-03-22 18:13:07', 1, 'First book on RoR')18:13:07', 1, 'First book on RoR')

Product Create (0.8ms)Product Create (0.8ms) INSERT INTO "products" INSERT INTO "products" ("name", "price", "created_at", "updated_at", "category_id", ("name", "price", "created_at", "updated_at", "category_id", "description") VALUES"description") VALUES('Ruby ''on Rails', 10.0, '2011-03-22 18:13:07', '2011-03-22 ('Ruby ''on Rails', 10.0, '2011-03-22 18:13:07', '2011-03-22 18:13:07', 1, 'First book on RoR')18:13:07', 1, 'First book on RoR')

log/development.log

Page 40: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Encore trop complexe ?

•Create

•Read

•Update

•Delete

Besoin d’un outil qui gère le CRUD en 1 commande:

Page 41: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Scaffold

Page 42: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

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)

Page 43: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

En images

Page 44: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Les relationsclass class CategoryCategory < <

ActiveRecord::BaseActiveRecord::Basehas_manyhas_many :products :products

endend

class class CategoryCategory < < ActiveRecord::BaseActiveRecord::Base

has_manyhas_many :products :productsendend

Une catégorie possède n produits

class class ProductProduct < < ActiveRecord::BaseActiveRecord::Base

belongs_tobelongs_to :category :categoryendend

class class ProductProduct < < ActiveRecord::BaseActiveRecord::Base

belongs_tobelongs_to :category :categoryendend

Un produit appartient à une catégorie

class class ProductProduct < < ActiveRecord::BaseActiveRecord::Base

has_and_belongs_to_manyhas_and_belongs_to_many :ca :categorytegory

endend

class class ProductProduct < < ActiveRecord::BaseActiveRecord::Base

has_and_belongs_to_manyhas_and_belongs_to_many :ca :categorytegory

endend

Une catégorie possède n produits et un produit n catégories

ou

Page 45: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Les finderProduct.find(Product.find(:all:all, , :conditions:conditions => { :price => => { :price => 18 })18 })Product.find(Product.find(:first:first))Product.find(Product.find(:last:last))

Product.find(Product.find(:all:all, , :conditions:conditions => { :price => => { :price => 18 })18 })Product.find(Product.find(:first:first))Product.find(Product.find(:last:last))

Plusieurs finder dynamiques:

Product.Product.find_by_namefind_by_name(‘rails’)(‘rails’)Product.Product.find_all_by_namefind_all_by_name(‘rails’)(‘rails’)Product.Product.find_by_name_and_pricefind_by_name_and_price(‘book’, 18)(‘book’, 18)

Product.Product.find_by_namefind_by_name(‘rails’)(‘rails’)Product.Product.find_all_by_namefind_all_by_name(‘rails’)(‘rails’)Product.Product.find_by_name_and_pricefind_by_name_and_price(‘book’, 18)(‘book’, 18)

Product.find(:all, Product.find(:all, :joins:joins => :category, => :category, :conditions:conditions => { :categories => { :name => => { :categories => { :name => "books" }})"books" }})

Product.find(:all, Product.find(:all, :joins:joins => :category, => :category, :conditions:conditions => { :categories => { :name => => { :categories => { :name => "books" }})"books" }})

Jointure:

Page 46: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Les scopeclass class ProductProduct < ActiveRecord::Base < ActiveRecord::Base

named_scopenamed_scope :recent, :recent, lambdalambda { { { { :conditions:conditions => ["created_at > ?", => ["created_at > ?", 5.days.ago5.days.ago] } } ] } } named_scopenamed_scope :limit, :limit, lambdalambda { |n| { { |n| { :limit:limit => n } } => n } } named_scopenamed_scope :ordered_by_name, { :ordered_by_name, { :order:order => "NAME ASC" } => "NAME ASC" }endend

class class ProductProduct < ActiveRecord::Base < ActiveRecord::Base named_scopenamed_scope :recent, :recent, lambdalambda { { { { :conditions:conditions => ["created_at > ?", => ["created_at > ?", 5.days.ago5.days.ago] } } ] } } named_scopenamed_scope :limit, :limit, lambdalambda { |n| { { |n| { :limit:limit => n } } => n } } named_scopenamed_scope :ordered_by_name, { :ordered_by_name, { :order:order => "NAME ASC" } => "NAME ASC" }endend

Invoquer les scope, de façon chaînable

Product.Product.recentrecent..ordered_by_nameordered_by_name..limitlimit(2)(2)Product Load (0.3ms)Product Load (0.3ms) SELECT * FROM "products" WHERE (created_at > SELECT * FROM "products" WHERE (created_at > '2011-03-17 21:08:24') ORDER BY NAME ASC LIMIT 2'2011-03-17 21:08:24') ORDER BY NAME ASC LIMIT 2

Product.Product.recentrecent..ordered_by_nameordered_by_name..limitlimit(2)(2)Product Load (0.3ms)Product Load (0.3ms) SELECT * FROM "products" WHERE (created_at > SELECT * FROM "products" WHERE (created_at > '2011-03-17 21:08:24') ORDER BY NAME ASC LIMIT 2'2011-03-17 21:08:24') ORDER BY NAME ASC LIMIT 2

Page 47: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Les validationsclass class ProductProduct < ActiveRecord::Base < ActiveRecord::Base

belongs_to :categorybelongs_to :categoryvalidates_presence_ofvalidates_presence_of :name, :category_id :name, :category_idvalidates_numericality_ofvalidates_numericality_of :price :price

class class ProductProduct < ActiveRecord::Base < ActiveRecord::Basebelongs_to :categorybelongs_to :categoryvalidates_presence_ofvalidates_presence_of :name, :category_id :name, :category_idvalidates_numericality_ofvalidates_numericality_of :price :price

et bien d’autres:

validates_confirmation_ofvalidates_exclusion_ofvalidates_format_ofvalidates_inclusion_ofvalidates_length_of…

Page 48: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

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

Page 49: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Le routeurconfig/routes.rb

ActionController::Routing::Routes.draw do |map|ActionController::Routing::Routes.draw do |map|# # RESTfulRESTful /categories/1/products/1/map. /categories/1/products/1/map.resourcesresources :categories do | :categories do |category|category|

category.resources :productscategory.resources :productsendend# route nommée# route nomméemap.map.purchasepurchase 'products/:id/purchase', :controller => 'catalog', :action 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'=> 'purchase'# namespace# namespacemap.map.namespacenamespace :admin do |admin| :admin do |admin|

# /admin/products# /admin/productsadmin.resource :productsadmin.resource :products

endend# route par défaut# route par défautmap.map.rootroot :controller => 'products' :controller => 'products'endend

ActionController::Routing::Routes.draw do |map|ActionController::Routing::Routes.draw do |map|# # RESTfulRESTful /categories/1/products/1/map. /categories/1/products/1/map.resourcesresources :categories do | :categories do |category|category|

category.resources :productscategory.resources :productsendend# route nommée# route nomméemap.map.purchasepurchase 'products/:id/purchase', :controller => 'catalog', :action 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'=> 'purchase'# namespace# namespacemap.map.namespacenamespace :admin do |admin| :admin do |admin|

# /admin/products# /admin/productsadmin.resource :productsadmin.resource :products

endend# route par défaut# route par défautmap.map.rootroot :controller => 'products' :controller => 'products'endend

Page 50: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Les routesrake routes categories categories GETGET /categories(.:format) /categories(.:format) {:controller=>"categories", :action=>"index"} {:controller=>"categories", :action=>"index"} POSTPOST /categories(.:format) {:controller=>"categories", :action=>"create"} /categories(.:format) {:controller=>"categories", :action=>"create"} new_category GET /categories/new(.:format) new_category GET /categories/new(.:format) {:controller=>"categories", :action=>"new"}edit_category GET {:controller=>"categories", :action=>"new"}edit_category GET /categories/:id/edit(.:format) {:controller=>"categories", :action=>"edit"} /categories/:id/edit(.:format) {:controller=>"categories", :action=>"edit"} category GET /categories/:id(.:format) category GET /categories/:id(.:format) {:controller=>"categories", :action=>"show"} {:controller=>"categories", :action=>"show"} PUTPUT /categories/:id(.:format) {:controller=>"categories", :action=>"update"} /categories/:id(.:format) {:controller=>"categories", :action=>"update"} DELETEDELETE /categories/:id(.:format) /categories/:id(.:format) {:controller=>"categories", :action=>"destroy"} products GET {:controller=>"categories", :action=>"destroy"} products GET /products(.:format) {:controller=>"products", :action=>"index"} /products(.:format) {:controller=>"products", :action=>"index"} POST /products(.:format) POST /products(.:format) {:controller=>"products", :action=>"create"} new_product GET {:controller=>"products", :action=>"create"} new_product GET /products/new(.:format) {:controller=>"products", :action=>"new"} /products/new(.:format) {:controller=>"products", :action=>"new"} edit_product GET /products/:id/edit(.:format) edit_product GET /products/:id/edit(.:format) {:controller=>"products", :action=>"edit"} product GET {:controller=>"products", :action=>"edit"} product GET /products/:id(.:format) {:controller=>"products", :action=>"show"} /products/:id(.:format) {:controller=>"products", :action=>"show"} PUT /products/:id(.:format) PUT /products/:id(.:format) {:controller=>"products", :action=>"update"} DELETE {:controller=>"products", :action=>"update"} DELETE /products/:id(.:format) {:controller=>"products", :action=>"destroy"} /products/:id(.:format) {:controller=>"products", :action=>"destroy"} /:controller/:action/:id /:controller/:ac /:controller/:action/:id /:controller/:action/:id(.:format) tion/:id(.:format) rootroot / / {:controller=>"products", :action=>"index"}{:controller=>"products", :action=>"index"}

categories categories GETGET /categories(.:format) /categories(.:format) {:controller=>"categories", :action=>"index"} {:controller=>"categories", :action=>"index"} POSTPOST /categories(.:format) {:controller=>"categories", :action=>"create"} /categories(.:format) {:controller=>"categories", :action=>"create"} new_category GET /categories/new(.:format) new_category GET /categories/new(.:format) {:controller=>"categories", :action=>"new"}edit_category GET {:controller=>"categories", :action=>"new"}edit_category GET /categories/:id/edit(.:format) {:controller=>"categories", :action=>"edit"} /categories/:id/edit(.:format) {:controller=>"categories", :action=>"edit"} category GET /categories/:id(.:format) category GET /categories/:id(.:format) {:controller=>"categories", :action=>"show"} {:controller=>"categories", :action=>"show"} PUTPUT /categories/:id(.:format) {:controller=>"categories", :action=>"update"} /categories/:id(.:format) {:controller=>"categories", :action=>"update"} DELETEDELETE /categories/:id(.:format) /categories/:id(.:format) {:controller=>"categories", :action=>"destroy"} products GET {:controller=>"categories", :action=>"destroy"} products GET /products(.:format) {:controller=>"products", :action=>"index"} /products(.:format) {:controller=>"products", :action=>"index"} POST /products(.:format) POST /products(.:format) {:controller=>"products", :action=>"create"} new_product GET {:controller=>"products", :action=>"create"} new_product GET /products/new(.:format) {:controller=>"products", :action=>"new"} /products/new(.:format) {:controller=>"products", :action=>"new"} edit_product GET /products/:id/edit(.:format) edit_product GET /products/:id/edit(.:format) {:controller=>"products", :action=>"edit"} product GET {:controller=>"products", :action=>"edit"} product GET /products/:id(.:format) {:controller=>"products", :action=>"show"} /products/:id(.:format) {:controller=>"products", :action=>"show"} PUT /products/:id(.:format) PUT /products/:id(.:format) {:controller=>"products", :action=>"update"} DELETE {:controller=>"products", :action=>"update"} DELETE /products/:id(.:format) {:controller=>"products", :action=>"destroy"} /products/:id(.:format) {:controller=>"products", :action=>"destroy"} /:controller/:action/:id /:controller/:ac /:controller/:action/:id /:controller/:action/:id(.:format) tion/:id(.:format) rootroot / / {:controller=>"products", :action=>"index"}{:controller=>"products", :action=>"index"}

Page 51: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Les contrôleursclass ProductsController < ApplicationControllerclass ProductsController < ApplicationController

before_filterbefore_filter :authenticate, :authenticate, :only:only => :index => :index

def def indexindex @products@products = Product.all #disponible dans la vue = Product.all #disponible dans la vuerespond_torespond_to do |format| do |format|

# GET /products# GET /productsformat.html # index.html.erbformat.html # index.html.erb# GET /products.xml# GET /products.xmlformat.xml { format.xml { renderrender :xml => :xml => @products@products } } endendendend

privateprivatedef def authenticateauthenticate# do some stuff# do some stuffendend

endend

class ProductsController < ApplicationControllerclass ProductsController < ApplicationControllerbefore_filterbefore_filter :authenticate, :authenticate, :only:only => :index => :index

def def indexindex @products@products = Product.all #disponible dans la vue = Product.all #disponible dans la vuerespond_torespond_to do |format| do |format|

# GET /products# GET /productsformat.html # index.html.erbformat.html # index.html.erb# GET /products.xml# GET /products.xmlformat.xml { format.xml { renderrender :xml => :xml => @products@products } } endendendend

privateprivatedef def authenticateauthenticate# do some stuff# do some stuffendend

endend

Page 52: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

La vue avec ActionView

•Les vues : pas forcément du HTML

•Layout

•Partials

•Helpers

Page 53: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Les types de vues

i18n des vuesapp/views/products/app/views/products/index.fr.html.erbindex.fr.html.erbapp/views/products/app/views/products/index.es.html.erbindex.es.html.erb

app/views/products/app/views/products/index.fr.html.erbindex.fr.html.erbapp/views/products/app/views/products/index.es.html.erbindex.es.html.erb

Rails >= 2.3

Différents formats

app/views/products/app/views/products/index.iphone.erbindex.iphone.erbapp/views/products/app/views/products/index.xml.erbindex.xml.erb

app/views/products/app/views/products/index.iphone.erbindex.iphone.erbapp/views/products/app/views/products/index.xml.erbindex.xml.erb

Page 54: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Le layoutSquelette de base app/views/app/views/layoutslayouts//

application.html.erbapplication.html.erbapp/views/app/views/layoutslayouts//application.html.erbapplication.html.erb

Modifiable depuis le contrôleur

<!DOCTYPE…><html><body><<!DOCTYPE…><html><body><%= %= yieldyield %></body></html> %></body></html><!DOCTYPE…><html><body><<!DOCTYPE…><html><body><%= %= yieldyield %></body></html> %></body></html>

Page 55: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Les partialsDes morceaux de vue

<!DOCTYPE…><html><body><!DOCTYPE…><html><body><%= render :<%= render :partialpartial => => ‘products/sidebar’ %><%= ‘products/sidebar’ %><%= yieldyield %></body></html>%></body></html>

<!DOCTYPE…><html><body><!DOCTYPE…><html><body><%= render :<%= render :partialpartial => => ‘products/sidebar’ %><%= ‘products/sidebar’ %><%= yieldyield %></body></html>%></body></html>

app/views/products/app/views/products/_sidebar.html.erb_sidebar.html.erbapp/views/products/app/views/products/_sidebar.html.erb_sidebar.html.erb

Page 56: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Exemple de vue: liste

<h1>Listing categories</h1><table> <tr> <h1>Listing categories</h1><table> <tr> <th>Name</th> </tr><% @categories.each do |category| <th>Name</th> </tr><% @categories.each do |category| %> <tr> <td><%=h %> <tr> <td><%=h truncatetruncate(category.name, :size => 10) (category.name, :size => 10) %></td> <td><%= link_to 'Show', category %></td> %></td> <td><%= link_to 'Show', category %></td> <td><%= link_to 'Edit', <td><%= link_to 'Edit', edit_category_pathedit_category_path(category) (category) %></td> <td><%= link_to 'Destroy', category, :%></td> <td><%= link_to 'Destroy', category, :confirmconfirm => => 'Are you sure?', :'Are you sure?', :methodmethod => :delete %></td> </tr><% end => :delete %></td> </tr><% end %></table><br /><%= link_to 'New category', %></table><br /><%= link_to 'New category', new_category_path %>new_category_path %>

<h1>Listing categories</h1><table> <tr> <h1>Listing categories</h1><table> <tr> <th>Name</th> </tr><% @categories.each do |category| <th>Name</th> </tr><% @categories.each do |category| %> <tr> <td><%=h %> <tr> <td><%=h truncatetruncate(category.name, :size => 10) (category.name, :size => 10) %></td> <td><%= link_to 'Show', category %></td> %></td> <td><%= link_to 'Show', category %></td> <td><%= link_to 'Edit', <td><%= link_to 'Edit', edit_category_pathedit_category_path(category) (category) %></td> <td><%= link_to 'Destroy', category, :%></td> <td><%= link_to 'Destroy', category, :confirmconfirm => => 'Are you sure?', :'Are you sure?', :methodmethod => :delete %></td> </tr><% end => :delete %></td> </tr><% end %></table><br /><%= link_to 'New category', %></table><br /><%= link_to 'New category', new_category_path %>new_category_path %>

Page 57: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Exemple de vue: édition

<% <% form_forform_for(@product) do |f| %> <%= f.error_messages %> (@product) do |f| %> <%= f.error_messages %> <p> <%= f.label :name %><br /> <%= f.<p> <%= f.label :name %><br /> <%= f.text_fieldtext_field :name :name %> </p><p> <%= f.label :description %><br /> <%= %> </p><p> <%= f.label :description %><br /> <%= f.f.text_areatext_area :description %> </p><p> <%= f.label :available :description %> </p><p> <%= f.label :available %><br /> <%= f.%><br /> <%= f.check_boxcheck_box :available %> </p><p> <%= :available %> </p><p> <%= f.label :category_id %><br /> <%= f.f.label :category_id %><br /> <%= f.selectselect :category_id, :category_id, (Category.all.map do |c| [c.name, c.id] end) %> </p><p> <(Category.all.map do |c| [c.name, c.id] end) %> </p><p> <%= f.%= f.submitsubmit 'Update' %> </p><% end %><%= 'Update' %> </p><% end %><%= link_tolink_to 'Show', @product %> |<%= 'Show', @product %> |<%= link_tolink_to 'Back', products_path %> 'Back', products_path %>

<% <% form_forform_for(@product) do |f| %> <%= f.error_messages %> (@product) do |f| %> <%= f.error_messages %> <p> <%= f.label :name %><br /> <%= f.<p> <%= f.label :name %><br /> <%= f.text_fieldtext_field :name :name %> </p><p> <%= f.label :description %><br /> <%= %> </p><p> <%= f.label :description %><br /> <%= f.f.text_areatext_area :description %> </p><p> <%= f.label :available :description %> </p><p> <%= f.label :available %><br /> <%= f.%><br /> <%= f.check_boxcheck_box :available %> </p><p> <%= :available %> </p><p> <%= f.label :category_id %><br /> <%= f.f.label :category_id %><br /> <%= f.selectselect :category_id, :category_id, (Category.all.map do |c| [c.name, c.id] end) %> </p><p> <(Category.all.map do |c| [c.name, c.id] end) %> </p><p> <%= f.%= f.submitsubmit 'Update' %> </p><% end %><%= 'Update' %> </p><% end %><%= link_tolink_to 'Show', @product %> |<%= 'Show', @product %> |<%= link_tolink_to 'Back', products_path %> 'Back', products_path %>

Page 58: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Autour de Rails

•Communauté active

•Autour de github

•Gems

•Authentification

•Pagination

•…

config/environment.rbRails::Initializer.run do |Rails::Initializer.run do |config|config|

config.gemconfig.gem ‘hpricot’ ‘hpricot’endend

Rails::Initializer.run do |Rails::Initializer.run do |config|config|

config.gemconfig.gem ‘hpricot’ ‘hpricot’endend

Page 59: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Documentation

•http://www.rubyonrails.org/

•http://guides.rubyonrails.org/

•http://apidock.com/rails

•http://railsforzombies.org/

•http://groups.google.com/group/railsfrance

Page 60: Ruby on Rails Supinfo 2011. A propos Martin Catty, fondateur de Synbioz Rubyiste depuis 2006 _fuse mcatty@synbioz.commcatty@synbioz.com

Merci, c’est à vous !

•Des questions ?

_fuse [email protected]