Framework de Programmation des Serveurs Web

Initiation à Ruby on Rails (RoR)

Olivier Dalle (@unice.fr)

Université de Nice Sophia Antipolis

Modèle Micropost


Une nouvelle resource REST

Modèle Micropost


Une nouvelle resource REST

Modèle Micropost


Une nouvelle resource REST

Modèle Micropost


Une nouvelle resource REST

$ rails generate model Micropost content:string user_id:integer

La migration générée pour micropost


La migration générée pour micropost


L’index nous servira à retrouver les posts par utilisateur et dans l’ordre inverse de celui de création.

Création du test

spec/models/micropost_spec.rb

Création du test

spec/models/micropost_spec.rb

Sans oublier:

$ bundle exec rake db:migrate
$ bundle exec rake db:test:prepare

Le modèle de données


Le modèle de données


Problème avec le code?


On verifie que les tests passent:

$ bundle exec rspec spec/models/micropost_spec.rb

Problème avec le code?


On verifie que les tests passent:

$ bundle exec rspec spec/models/micropost_spec.rb

Ok

Problème avec le code?


Problème avec le code?


On ajoute les tests de validite:

spec/models/micropost_spec.rb

Problème avec le code?


On ajoute les tests de validite et on fait passer les tests au vert:

Problème avec le code?


On ajoute les tests de validité et on fait passer les tests au vert:

Tous les attributs sont accessibles
=> Un client malicieux peut changer les affectations

Association user/microposts


Association user/microposts

Méthodes rails pour les associations


Méthodes rails pour les associations


Différences entre méthodes de la classe mp et méthodes d’association

Méthodes rails pour les associations


Différences entre methodes de la classe mp et méthodes d’association

Méthodes rails pour les associations


Différences entre méthodes de la classe mp et méthodes d’association

Méthodes rails pour les associations


Différences entre méthodes de la classe mp et méthodes d’association

Méthodes rails pour les associations


On peut corriger le code du test:

Méthodes rails pour les associations


On peut corriger le code du test:

Méthodes rails pour les associations


On peut corriger le code du test:

C’est la facon canonique pour créer des microposts: a travers l’association user:

Méthodes rails pour les associations


On peut corriger le code du test:

C’est la facon canonique pour créer des microposts: a travers l’association user:
user_id est mis à jour automatiquement

Le Problème de sécurité est toujours là


Créer les MP à travers l’association ne corrige pas le problème de sécurité:

Le Problème de sécurité est toujours là


Créer les MP à travers l’association ne corrige pas le problème de sécurité:

Le Problème de sécurité est toujours là


Créer les MP à travers l’association ne corrige pas le problème de sécurité:

Le Problème de sécurité est toujours là


Créer les MP à travers l’association ne corrige pas le problème de sécurité:

Le test complet sur le modèle microposts

spec/models/micropost_spec.rb

Correction sur le test modèle user


Vérifier la présence de l’attribut microposts:
spec/models/user_spec.rb

Correction sur le test modèle user


Vérifier la présence de l’attribut microposts:
spec/models/user_spec.rb

Et les modèles corrigés


Et les modèles corrigés

Amélioration du modèle micropost


On ajoute:

Amélioration du modèle micropost


On ajoute:

Amélioration du modèle micropost


On ajoute:

Amélioration du modèle micropost


On ajoute:

Amélioration du modèle micropost


On ajoute:

Usine à micropost


spec/factories.rb

Test sur les associations


On souhaite que les MP sortent en ordre chronologique inverse

Test sur les associations


On souhaite que les MP sortent en ordre chromologique inverse

Dans les tests, on crée des MP avec des dates différentes:

FactoryGirl.create(:micropost, user: @user, created_at: 1.day.ago)
FactoryGirl.create(:micropost, user: @user, created_at: 1.hour.ago)

Test sur les associations


On souhaite que les MP sortent en ordre chromologique inverse

Dans les tests, on crée des MP avec des dates différentes:

FactoryGirl.create(:micropost, user: @user, created_at: 1.day.ago)
FactoryGirl.create(:micropost, user: @user, created_at: 1.hour.ago)

(Et dans le mauvais ordre.)

Test sur les associations

spec/models/user_spec.rb

Imposer un ordre sur les microposts


On utilise un mécanisme rails: default_scope

Imposer un ordre sur les microposts


On utilise un mécanisme rails: default_scope

Destruction en cascade


Que faire des posts d’un utilisateur si son compte est détruit?

Destruction en cascade


Que faire des posts d’un utilisateur si son compte est détruit?

Les détruire aussi

Destruction en cascade


Que faire des posts d’un utilisateur si son compte est détruit?

Les détruire aussi

Problème:

$ rails console --sandbox
>> @user = User.first
>> microposts = @user.microposts
>> @user.destroy
>> microposts
=> []

Destruction en cascade


Que faire des posts d’un utilisateur si son compte est détruit?

Les détruire aussi

Solution = copie (dup) au lieu de reférence:


$ rails console
>> a = [1, 2, 3]
=> [1, 2, 3]
>> b = a.dup
=> [1, 2, 3]
>> a.reverse!
=> [3, 2, 1]
>> a
=> [3, 2, 1]
>> b
=> [1, 2, 3]

Copie de surface (shallow copy).

Destruction en cascade (le test)

spec/models/user_spec.rb

Destruction en cascade (solution)


Moins d’une ligne de code suffit pour faire passer le test au vert:

Destruction en cascade (solution)


Moins d’une ligne de code suffit pour faire passer le test au vert:
app/models/user.rb

Validation du content des microposts

spec/models/micropost_spec.rb

Validation du content des microposts


app/models/micropost.rb

Visualisation des MicroPosts


Visualisation des MicroPosts


Visualisation des MicroPosts


Visualisation des MicroPosts


Visualisation des MicroPosts


Visualisation des MicroPosts


Visualisation des MicroPosts


Visualisation des MicroPosts

Modification de la page utilisateur


On doit (bien-sûr) commencer par les tests:

Modification de la page utilisateur


On doit (bien-sûr) commencer par les tests:

Modification de la page utilisateur


On doit (bien-sûr) commencer par les tests:

NB: let! force la m-a-j de l’association

Modification de la page utilisateur


On doit (bien-sûr) commencer par les tests:

Quel type de test?

Modification de la page utilisateur


On doit (bien-sûr) commencer par les tests:

Quel type de test?

Test d’affichage d’une page = integration

Modification de la page utilisateur


On doit (bien-sûr) commencer par les tests:

Quel type de test?

Test d’affichage d’une page = integration

spec/requests/user_pages_spec.rb

Test pour visualisation des MP sur page utilisateur

spec/requests/user_pages_spec.rb

Modification de la page utilisateur


app/views/users/show.html.erb

Modification de la page utilisateur


app/views/users/show.html.erb

Notez l’utilisation de will_paginate et d’une vue partielle…

Vue partielle des MPs


app/views/microposts/_micropost.html.erb

Modification du contrôleur User


Nous utilisons une nouvelle variable lors de l’affichage de la page utilisateur (@microposts)

Modification du contrôleur User


Nous utilisons une nouvelle variable lors de l’affichage de la page utilisateur (@microposts)

app/controllers/users_controller.rb

Création de MP factices


La page de l’utilisateur est vide de MP…

Création de MP factices


La page de l’utilisateur est vide de MP…
Ennuyeux pour tester l’affichage…

Création de MP factices


La page de l’utilisateur est vide de MP…
Ennuyeux pour tester l’affichage…
Modifions la tâche rake db:populate.

lib/tasks/sample_data.rake

Création de MP factices


Puis on exécute:

$ bundle exec rake db:reset
$ bundle exec rake db:populate
$ bundle exec rake db:test:prepare

Création de MP factices

Une touche de style pour les MPs

app/assets/stylesheets/custom.css.scss

Une touche de style pour les MPs

Une touche de style pour les MPs

Manipulation des MPs


Création de MP par l’interface web:

Manipulation des MPs


Création de MP par l’interface web:

Manipulation des MPs


Création de MP par l’interface web:

Contrôle d’accès


Une règle simple: seuls les utilisateurs connus ont le droit d’exécuter les actions create et destroy

Contrôle d’accès


Une règle simple: seuls les utilisateurs connus ont le droit d’exécuter les actions create et destroy

On commence par le test:

Contrôle d’accès


Une règle simple: seuls les utilisateurs connus ont le droit d’exécuter les actions create et destroy

On commence par le test:

Pour les utilisateurs connectés, on verra plus tard…

Test du contrôle d’accès

Test du contrôle d’accès


Remarquez:

Test du contrôle d’accès


Remarquez:

Test du contrôle d’accès


Remarquez:

Implémentation du contrôle d’accès


Un peu de refactoring:

Implémentation du contrôle d’accès


Un peu de refactoring:

Implémentation du contrôle d’accès


Un peu de refactoring:

Implémentation du contrôle d’accès

Un peu de refactoring:

Implémentation du contrôle d’accès


La méthode signed_in_user est maintenant dans le helper

Implémentation du contrôle d’accès


La méthode signed_in_user est maintenant dans le helper

Implémentation du contrôle d’accès

La méthode signed_in_user est maintenant dans le helper

Création des microposts

Création des microposts

Création des microposts


On commence par les tests

Création des microposts


On commence par les tests

$ rails generate integration_test micropost_pages

Création des microposts


spec/requests/micropost_pages_spec.rb (haut)

Création des microposts


spec/requests/micropost_pages_spec.rb (bas)

Création des microposts


L’action create est analogue à celle des user:
app/controllers/microposts_controller.rb

Création des microposts


Ensuite on doit ajouter un lien pour la création sur la page d’accueil:
app/views/static_pages/home.html.erb

Création des microposts


Il reste deux partial à ajouter:
(1/2) app/views/shared/_user_info.html.erb

Création des microposts


Il reste deux partial à ajouter:
(2/2) app/views/shared/_micropost_form.html.erb

Création des microposts


Il faut aussi préparer une instance de mp dans le contrôleur qui affiche la page d’accueil:

Création des microposts


Il faut aussi préparer une instance de mp dans le contrôleur qui affiche la page d’accueil:
app/controllers/static_pages_controller.rb

Création des microposts


Il faut aussi rendre le partial d;affichage d’erreur indépendant du type d’objet:
Il doit pouvoir être appelé de la facon suivante:

Création des microposts


Il faut aussi rendre le partial d;affichage d’erreur indépendant du type d’objet:
Il doit pouvoir être appelé de la facon suivante:

app/views/shared/_error_messages.html.erb

Création des microposts


La dernière modif a cassé le formulaire d’enregistrement des utilisateurs. On corrige:
app/views/users/new.html.erb

Création des microposts


La dernière modif a aussi cassé le formulaire d’édition des utilisateurs. On corrige:
app/views/users/edit.html.erb

Création des microposts

Affichage des micro-posts

Affichage des feed de micro-posts


Le test doit s’assurer que:

Affichage des feed de micro-posts


Le test doit s’assurer que:

L’implem recherche les mp d’un utilisateur donné:

Affichage des feed de micro-posts


Ensuite on doit s’attaquer à l’affichage:

Destruction des microposts

Destruction des microposts


A finir en exercice….