Form Objects

@Semeia

5. Une autre variante d'implémentation

 

6. Comment on adopte ça dans une codebase existante ?

 

7. Q&A

1. Qu'est-ce que c'est ?

 

2. Quand est-ce que j'en ai besoin ?

 

3. Comment ça s'utilise ?

 

4. Comment ça s'implémente ?

Glossaire

1

Qu'est-ce que c'est ?

On sort les validations des modèles pour les mettre dans des classes associés (fonctionellement) aux formulaires

 

Donc -> les validations sont différentes en fonction de la provenance des données

 

Donc -> il est toujours possible qu'un record soit crée avec zéro validations

 

Donc -> on ne peux jamais considérer les données comme fiables

Form Objects

Les validations se font dans les modèles

 

Donc -> les validation sont identiques peu importe la provenance des données

 

Donc -> on assure une homogénéité des données dans la DB

Vanilla

2

Quand est-ce que j'en ai besoin ?

"Sur l'action de réservation du service, on envoie un SMS de confirmation, donc je dois valider que le numéro de téléphone est renseigné"

 

Ce genre de validation n'est pertinente que pour une scénario particulier

 

Plutôt POUR les forms objects

Validations contextuelles

 

 

"Je dois valider que, si le numéro de téléphone est renseigné, alors il doit respecter tel format"

 

Ce genre de validation est vraie TOUT LE TEMPS

 

Plutôt PAS de form objects

Validations de cohérence des données

Débat

Est-ce que vous avez des cas pertinents chez Semeia ?

Est-ce que vous avez déjà souffert d'un mic-mac de validations ?

Est-ce que vous trouvez ça surcôté ?

3

Comment ça s'utilise ?

il liste toutes les validations à effectuer

Le form object

On initialise le form object avec l'objet qu'on veut valider

 

On récupére via le form objects le statut de la validation

L'appel

4

Comment ça s'implémente ?

`for_model' permet d'avoir accès à tt les champs de la DB

 

`validate' (via ActiveModel::Validations) permet d'agglomérer les validations écrites dans le form, et celles écrites dans le model

 

`assign_params' permet de faire passer les params via le form object

Implémentation simple

On extend simplement la singleton class de l'objet à valider

 

(on pourrait argumenter que ce style d'implémentation n'est PAS du form object, vu qu'on ne crée pas d'objet supplémentaire)

Implémentation encore plus simple

Débat

Quelle version de l'implématation vous préférez ?

Et pourquoi ?

Quelle features pour un système plus complet ?

5

Une autre variante d'implémentation

On veut pouvoir partager des blocs de validations sur plusieurs forms

 

Idée -> On va nommer les blocks dans lesquels on écrit les validations, et comme ça on pourra utiliser un bloc juste via son nom

 

exemple d'usage : user_validator

implem : form:43

DRY

On réutilise les validations Rails

 

Idée -> On va écrire les validations dans des blocks, et on injectera ces blocks dans l'objet au moment de la validation

 

exemple d'usage : brand_validator

implem : form.rb:236

Ne pas réinventer la roue

On veut pouvoir modifier la valeur d'un params entre l'entrée utilisateur et ce qu'on veut save

 

Idée -> on permet de passer un block qu'on exécutera au moment de l'assignation des params

 

exemple d'usage : panel_message_validator:17

implem : form/attribute:14

Transform Params

On veut que le form soit responsable de la logique de filtrage des params

 

Idée -> En plus des validations, on va lister dans le form tous les params qui sont autorisée

 

exemple d'usage : gru/update_ride_form

exemple d'usage : pass_mobilite/ride_form

implem : form:219

Strong Params

On veut pouvoir utiliser et valider des params qui ne sont pas associés à des colonnes dans la DB

 

Idée -> on permet de déclarer des attributs, et on ira déclare un `attr_accessor' au moment de l'assignation des params

 

exemple d'usage : ride_validator:32

implem : form/attribute:186

Fake Params

On veut pouvoir faire des "raccourcis" entre plusieurs params

 

Idée -> On permet de passer un block pour calculer un param à partir d'un autre

 

exemple d'usage : capture_access_validator:24

implem : form:192

Inferring Params

On veut pouvoir valider des nested params, ceux qu'on envoie quand on utilise le `accept_nested_attributes' dans Rails

 

Idée -> On permet de passer un Form dans le form

 

exemple d'usage : superuser/instant_commute_form

implem : form:271

Nested Forms

Débat

Est-ce que cette implémentation est parfaite ?

Qu'est-ce qu'il faudrait changer ?

Si c'était en prod, est-ce qu'on prend la décision de changer ?

6

Comment on adopte ça dans une codebase existante ?

Dans le "guide of the développeur", on avait déjà acté le style général à adopter pour des gros refacto

Méthodologie Globale

On avait aussi décidé (lors d'une réunion d'équipe) de pousser la transition au max, jusqu'à ne plus avoir aucune validation dans les modèles

Hard Line

On avait enfin crée un module qui renvoyait explicitement une erreur si un développeur ne respectait pas cette régle d'architecture

 

En permettant cependant des exceptions explicites

Automatisation

Débat

Et vous, comment vous faites vos grosses transitions ?

Vous en pensez quoi de cette méthode ?

Avoir des documents de référence sur les guidelines de code, on aime bien ?

7

Q&A

 

Fin

deck

By Thomas Petrachi