Framework de Programmation des Serveurs Web

Initiation à Ruby on Rails (RoR)

Olivier Dalle (@unice.fr)

Université de Nice Sophia Antipolis

Application Demo


Version simplifiée de Twitter:

Pour illustrer la puissance des générateur RoR

Sera redévelopée entièrement sans générateur.

Commencer l’application


Jeter les bases de l’applications démo (déjà vu):

  1. Création du squelette
     
    $ cd ~/rails_project
    $ rails new demo_app 
    $ cd demo_app
    

Commencer l’application


Jeter les bases de l’applications démo (déjà vu):

  1. Création du squelette
  2. Mise-à-jour Gemfile
    (Gemfile) source 'http://rubygems.org'
    (Gemfile) gem 'rails', '3.0.17'
    

Puis

$ bundle install

Commencer l’application


Jeter les bases de l’applications démo (déjà vu):

  1. Création du squelette
  2. Mise-à-jour Gemfile
  3. Initialiser un repo Git local
    
    $ git init
    $ git add .
    $ git commit -m "Import initial."
    

Commencer l’application


Jeter les bases de l’applications démo (déjà vu):

  1. Création du squelette
  2. Mise-à-jour Gemfile
  3. Initialiser un repo Git local
  4. Créer un repo distant sur GitHub puis sauver
    
    $ git remote add origin git@github.com:<username>/demo_app.git
    $ git push
    

Le modèle de données


Le modèle de données


Le modèle de données


Le modèle de données


Le modèle de données utilisateurs:

users
id integer
name string
email string

Le modèle de données


Le modèle de données utilisateurs:

users
id integer
name string
email string
Le modèle de données micro-posts:

micro-posts
id integer
contenu string
user_id integer

Génération des resources


En jargon rails, les abstractions (tables) sont des “resources”

Génération de la resource utilisateur:

$ rails generate scaffold User name:string email:string
	invoke  active_record
	create    db/migrate/20120919101927_create_users.rb
	create    app/models/user.rb
	invoke    test_unit
	create      test/unit/user_test.rb
	create      test/fixtures/users.yml
 	route  resources :users
	...

Migration de la base de données


La création des nouveaux fichiers est sans effet sur la BDD…

Migration = faire évoluer la BDD:


$ rake db:migrate
==  CreateUsers: migrating ====================================================
-- create_table(:users)
   -> 0.0008s
==  CreateUsers: migrated (0.0008s) ===========================================

( à propos de Rake… )


Rake = “Ruby make”

Exécution de tâches ruby.

Liste de tâches visant la BDD:

$ rake -T db

Liste de toutes les tâches:

$ rake -T

Lancer l’application demo


Lancer le serveur:

$ rails s

Alors quoi de neuf?
Comment accéder aux
nouvelles pages?

Philosophie REST


Chaque action est associée à une URL explicite

URL Action Rôle
/users
index
liste de tous les utilisateurs
/users/1
show
affiche la page de l’utilisateur 1
/users/new
new
formulaire de création d’un utilisateur
/users/1/edit
edit
formulaire d’édition d’un utilisateur

Convention over configuration


Chaque action est associée à une URL explicite …

… et Rails (et scaffold) se charge de fournir une implémentation par défaut.

index new

Convention over configuration


Chaque action est associée à une URL explicite…

… et Rails (et scaffold) se charge de fournir une implémentation par défaut.

show edit

Philosophie Rails


L’implémentation par défaut est totalement fonctionnelle.

Exemple: chaque action peut afficher un message contextuel.

edited created

A propos des actions REST


Seulement 4 actions?

A propos des actions REST


Seulement 4 actions?

created

Les Routes REST


verbe HTTP URL Action Rôle
GET
/users
index
liste de tous les utilisateurs
GET
/users/1
show
affiche la page de l’utilisateur 1
GET
/users/new
new
formulaire de création d’un utilisateur
GET
/users/1/edit
edit
formulaire d’édition d’un utilisateur

Les Routes REST


verbe HTTP URL Action Rôle
POST
/users
create
Crée un nouvel utilisateur (soumission formulaire)
PUT
/users/1
update
Màj utilisateur 1 (soumission formulaire)
DELETE
/users/1
delete
Destruction utilisateur 1

Le Patron de conception MVC en action

MVC_en_action

Configuration des routes


Le fichier config/routes.rb


FirstApp::Application.routes.draw do
	resources :users
	.
	.
	.
end

Généré automatiquement par scaffold.

Le controller


Une classe avec une méthode pour chaque action dans app/controllers/users_controller.rb:

class UsersController < ApplicationController
def index
  ...  
end
def show
  ...
end
def new
...
end
def edit
...
end
def create
...
end
def update
...
end
def destroy
...
end
end

communication entre contrôleur et modèle


Utilisation d’une variable d’instance (@users):


def index
	@users = User.all
end

Le model


Une classe User (sans s ici) dans app/models/user.rb:


	class User < ActiveRecord::Base
	end

La classe est vide! Le code utile est déjà en grande partie écrit dans la classe parente ActiveRecord::Base

La view


Fichier html dynamique avec instructions ruby (dans app/views/users/index.html.erb)

<h1>Listing users</h1>
<table><tr>
    <th>Name</th>
    <th>Email</th>
    <th></th>
    <th></th>
    <th></th>

La view


Fichier html dynamique avec instructions ruby (dans app/views/users/index.html.erb)

index_erb

Faiblesses de la ressource user


La resource micropost


On utilise scaffold et rake de la même facon que pour user


$ rails generate scaffold Micropost content:string user_id:integer
$ rake db:migrate

Les fichiers pour les routes, controller, modèle et vues sont cr&eacte;es de la même facon…

Validation du contenu


On ajoute une instruction pour limiter la longueur du micropost:


class Micropost < ActiveRecord::Base
  validates :content, :length => { :maximum => 140 }
end

Validation du contenu


On vérifie (ici 40 max seulement)

invalid

Relation entre user et micropost


Relation entre user et micropost


Utilisation de la relation


Exemple a partir de la console RoR:

console

Déploiement de l’App


On commence par sauvegarder la version:

$ git add .
$ git commit -a -m "Demo terminee"
$ git push

Puis on déploie sur Heroku:

$ heroku create
$ git push heroku master
$ heroku rake db:migrate

Mise a jour de la BDD sur Heroku


Pour appliquer les migrations on doit installer un nouveau gem:

$ sudo gem install taps
$ heroku db:push