Framework de Programmation des Serveurs Web

Initiation à Ruby on Rails (RoR)

Olivier Dalle (@unice.fr)

Université de Nice Sophia Antipolis

Enregistrement des utilisateurs


Enregistrement des utilisateurs


Enregistrement des utilisateurs


Visualisation des utilisateurs


Le profile visé à la fin de ce chapitre

Visualisation des utilisateurs


Le profile visé à la fin du tutoriel

Informations de debug


app/views/layouts/application.html.erb

Informations de debug


Un peu de style pour une jolie boite de debug app/assets/stylesheets/custom.css.scss

Informations de debug


Un peu de style pour une jolie boite de debug app/assets/stylesheets/custom.css.scss

Notez la syntaxe @mixin qui permet de factoriser des déclarations

Informations de debug

A propos des environements



$ rails console 
Loading development environment
>> Rails.env
=> "development"
>> Rails.env.development?
=> true
>> Rails.env.test?
=> false

A propos des environements



$ rails console 
Loading development environment
>> Rails.env
=> "development"
>> Rails.env.development?
=> true
>> Rails.env.test?
=> false

$ rails console test
Loading test environment
>> Rails.env
=> "test"
>> Rails.env.test?
=> true

A propos des environements



$ rails console 
Loading development environment
>> Rails.env
=> "development"
>> Rails.env.development?
=> true
>> Rails.env.test?
=> false

$ rails console test
Loading test environment
>> Rails.env
=> "test"
>> Rails.env.test?
=> true

Et pour lancer le serveur en mode prod:

$ rails server --environment production

A propos des environements


Et pour lancer le serveur en mode prod:

$ rails server --environment production

Attention…

A propos des environements


Et pour lancer le serveur en mode prod:

$ rails server --environment production

Attention, ne fonctionne que si la DB est initialisée:

$ bundle exec rake db:migrate RAILS_ENV=production

La ressource utilisateur


D’après le principe de l’architecture REST:

La ressource utilisateur


D’après le principe de l’architecture REST:

La ressource utilisateur


D’après le principe de l’architecture REST:

La ressource utilisateur


D’après le principe de l’architecture REST:

La ressource utilisateur


D’après le principe de l’architecture REST:

Essayons:

La ressource utilisateur


Routage REST


On peut ajouter une ressource et le routage auto des actions:

Routage REST


On peut ajouter une ressource et le routage auto des actions:

Routage REST


On peut ajouter une ressource et le routage auto des actions:

Routage REST


Routage REST


N’oublions pas le contrôleur


S’il n’existe pas on obtient ce message:

N’oublions pas le contrôleur


S’il n’existe pas on obtient ce message:

N’oublions pas le contrôleur


S’il n’existe pas on obtient ce message:

Pour le créer:

N’oublions pas le contrôleur


S’il n’existe pas on obtient ce message:

Pour le créer:

$ rails generate controller Users new --no-test-framework

N’oublions pas le contrôleur


S’il existe on obtient ce message:

N’oublions pas le contrôleur


S’il existe on obtient ce message:

N’oublions pas le contrôleur


S’il existe on obtient ce message:

Ajoutons une vue dans app/views/users/show.html.erb:

N’oublions pas le contrôleur


La vue a besoin d’un peu de préparation dans le contrôleur:

N’oublions pas le contrôleur


La vue a besoin d’un peu de préparation dans le contrôleur:

N’oublions pas le contrôleur


La vue a besoin d’un peu de préparation dans le contrôleur:

N’oublions pas le contrôleur


La vue a besoin d’un peu de préparation dans le contrôleur:

N’oublions pas le contrôleur


Passons aux tests


Jusque là nous avions:

Passons aux tests


On veut ajouter quelque-chose comme:

Passons aux tests


On veut ajouter quelque-chose comme:

Au lieu d’utiliser Active Records, on utilise une factory.

L’Usine Factory Girls

On ajoute une nouveau gem au Gemfile:

L’Usine Factory Girls

On ajoute une nouveau gem au Gemfile:

L’Usine Factory Girls

On ajoute une nouveau gem au Gemfile:

Puis

$ bundle install

L’Usine Factory Girls


Ensuite on peut construire une “usine a utilisateur” dans spec/factories.rb:

L’Usine Factory Girls


Il ne reste plus qu’à compléter le test avec:

let(:user) { FactoryGirl.create(:user) }

L’Usine Factory Girls


Et ensuite vérifier que ce test échoue:

Passer le test


Il suffit de changer app/views/users/show.html.erb:

Passer le test


Il suffit de changer app/views/users/show.html.erb:

Et relancer le test:

$ bundle exec rspec spec/

Un truc en passant …

Un truc en passant …


… pour accélerer les tests (config/environments/test.rb):

Formulaire d’enregistrement


Pour l’instant pas grand chose:

Formulaire d’enregistrement


Le résultat souhaité:

RAZ BDD


Comme on va se munir d’un formulaire, on peut vider la BD:

RAZ BDD


Comme on va se munir d’un formulaire, on peut vider la BD:

$ bundle exec rake db:reset

RAZ BDD


Comme on va se munir d’un formulaire, on peut vider la BD:

$ bundle exec rake db:reset

Et la BD de test:

$ bundle exec rake db:test:prepare

Tests du formulaire:


Tests du formulaire:


Apercu de la syntaxe:

Tests du formulaire:


Zoom sur le remplissage du formulaire:

Test de la création effective


S’appuie sur le nombre d’enregistrements trouvés

$ rails console
>> User.count
=> 0

Test données manquantes/invalides


Test données valides


Très similaire:

Le formulaire avec form_for

Le formulaire avec form_for

Execution d’un test en particulier


$ bundle exec rspec spec/requests/user_pages_spec.rb \
-e "signup page"

Execution d’un test en particulier


$ bundle exec rspec spec/requests/user_pages_spec.rb \
-e "signup page"

Le paramètre -e permet de choisir l’exemple a tester

Mise à jour du contrôleur


On Décore un peu…


app/assets/stylesheets/custom.css.scss

Et voilà !

Echec d’enregistrement


Un mockup d’exemple

On commence par tester …


Que les tests de soumission invalide passent.

On commence par tester …


Que les tests de soumission invalide passent.

$ bundle exec rspec spec/requests/user_pages_spec.rb \
-e "signup with invalid information"

On commence par tester …


Que les tests de soumission invalide passent.

$ bundle exec rspec spec/requests/user_pages_spec.rb \
-e "signup with invalid information"

Echec.

On commence par faire réussir le test


Failures:

1) User pages signup with invalid information should not create a user Failure/Error: expect { click_button submit }.not_to change(User, :count) ActionView::MissingTemplate: Missing template users/create, application/create with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :coffee]}. Searched in:
  • “/home/l3rails/rails_project/example_app/app/views”
  • (eval):2:in `click_button’
  • ./spec/requests/user_pages_spec.rb:23:in `block (5 levels) in <top (required)>’
  • ./spec/requests/user_pages_spec.rb:23:in `block (4 levels) in <top (required)>’

On commence par faire réussir le test


Cause?

On commence par faire réussir le test


Cause?

On commence par faire réussir le test


Cause? Voyons le test:

describe "with invalid information" do
      it "should not create a user" do
        expect { click_button submit }.not_to change(User, :count)
      end
    end

On commence par faire réussir le test


Cause? Voyons le test:

describe "with invalid information" do
      it "should not create a user" do
        expect { click_button submit }.not_to change(User, :count)
      end
    end

On commence par faire réussir le test


Si la validation échoue (formulaire vide):

On commence par faire réussir le test


Si la validation échoue (formulaire vide):

On commence par faire réussir le test


Si la validation échoue (formulaire vide):

Que faire dans ce cas?

On commence par faire réussir le test


Si la validation échoue (formulaire vide):

Que faire dans ce cas?
Afficher a nouveau le formulaire!

On commence par faire réussir le test


Afficher à nouveau le formulaire:

   def create
    @user = User.new(params[:user])
    if @user.save
      # Handle a successful save.
    else
      render 'new'
    end
  end

On essaie une soumission invalide

On essaie une soumission invalide

On essaie une soumission invalide


Les données sont bien envoyées:

---
user:
  name: Foo Bar
  password_confirmation: foo
  password: bar
  email: foo@invalid
commit: Create my account
action: create
controller: users

On essaie une soumission invalide


Les données sont bien envoyées… Mais rien ne s’affiche.

On essaie une soumission invalide


Les données sont bien envoyées… Mais rien ne s’affiche.
Il manque un message d’erreur.

Enregistrement avec message d’erreur


Jouons un peu à la console:

>> user = User.new(name: “Foo Bar”, email: “foo@invalid”,
?>                 password: “dude”, password_confirmation: “dude”)
>> user.save
=> false
>> user.errors.full_messages
=> [“Email is invalid”, “Password is too short (minimum is 6 characters)”]

Enregistrement avec message d’erreur


Jouons un peu à la console:

>> user = User.new(name: “Foo Bar”, email: “foo@invalid”,
?>                 password: “dude”, password_confirmation: “dude”)
>> user.save
=> false
>> user.errors.full_messages
=> [“Email is invalid”, “Password is too short (minimum is 6 characters)”]

Les erreurs sont bien là, il suffit de les afficher.

Enregistrement avec message d’erreur


Les erreurs sont bien là, il suffit de les afficher:

Enregistrement avec message d’erreur


Les erreurs sont bien là, il suffit de les afficher:

Parenthèse a propos de pluralize


>> include ActionView::Helpers::TextHelper
>> pluralize(1, “error”)
=> “1 error” 
>> pluralize(5, “error”)
=> “5 errors”
>> pluralize(2, “woman”)
=> “2 women”
>> pluralize(3, “erratum”)
=> “3 errata”

Enregistrement avec message d’erreur


Les erreurs sont bien là, il suffit de les afficher:

/* forms */
[...]
#error_explanation {
  color: #f00;
  ul {
    list-style: none;
    margin: 0 0 18px 0;
  }
}

.field_with_errors {
  @extend .control-group;
  @extend .error;
 } 

Enregistrement avec message d’erreur

Enregistrement avec succès


En cas de succès:

Enregistrement avec succès


En cas de succès:

Enregistrement avec succès


En cas de succès:

Enregistrement avec succès


En cas de succès:

Enregistrement avec succès

Et après?


Le test suivant échoue toujours:

$ bundle exec rspec spec/requests/user_pages_spec.rb \
> -e "signup with valid information"

Et après?


Le test suivant échoue toujours:

Il reste un commentaire à remplacer ici:

Et après?


Le test suivant échoue toujours:

Il reste un commentaire à remplacer ici:

  def create
    @user = User.new(params[:user])
    if @user.save
      # Handle a successful save.
    else
      render 'new'
    end
  end

Et après?


Le test suivant échoue toujours:

Il reste un commentaire à remplacer ici:

  def create
    @user = User.new(params[:user])
    if @user.save
      redirect_to @user
    else
      render 'new'
    end
  end

Et après ??


Un flash info!

Et après ??


Un flash info!

Un message qui apparaît sur la page suivante…

Et après ??


Un flash info!

Un message qui apparaît sur la page suivante…

Affiche le contenu de la variable flash:

Le flash info


On commence par ajouter le layout dans le template de la page
(app/views/layouts/application.html.erb)

Le flash info


On commence par ajouter le layout dans le template de la page
(app/views/layouts/application.html.erb)

Le flash info


Et ensuite il ne reste qu’a insérer le message dans la contrôleur:

Le flash info


Et ensuite il ne reste qu’a insérer le message dans la contrôleur:

Le flash info


Une dernière touche de sécurité


login, password, données personnelles…
Transmission de ces données critiques en clair?

Une dernière touche de sécurité


login, password, données personnelles…
Transmission de ces données critiques en clair?

La réponse: OpenSSL:
config/environments/production.rb