portaldacalheta.pt
  • Principal
  • Science Des Données Et Bases De Données
  • Conception Mobile
  • Design De Marque
  • Personnes Et Équipes Produit
La Technologie

Build Dumb, Refactor Smart: Comment masser les problèmes avec du code Ruby on Rails



Daniel Lewis a été un professionnel Développeur Ruby on Rails depuis plus de 4 ans, travaillant sur une douzaine d'applications Web à fort trafic, dont beaucoup via ApeeScape.

Parfois, les clients nous font des demandes de fonctionnalités que nous n'aimons vraiment pas. Ce n’est pas que nous n’aimons pas nos clients, nous aimons nos clients. Ce n'est pas que nous n'aimions pas cette fonctionnalité: la plupart des fonctionnalités demandées par les clients sont parfaitement alignées sur leurs objectifs commerciaux et leurs revenus.

Parfois, nous n'aimons pas une demande de fonctionnalité, car le moyen le plus simple de la résoudre est d'écrire du mauvais code, et nous n'avons pas de solution élégante en tête. Cela enverra beaucoup d'entre nous Développeurs Rails sur des recherches infructueuses à travers RubyToolbox , GitHub , blogs de développeurs et StackOverflow à la recherche d'un bijou, d'un plugin ou d'un exemple de code qui nous fera nous sentir mieux dans notre peau.



Parfois, nous n'aimons pas une demande de fonctionnalité car le moyen le plus simple de la résoudre est d'écrire du mauvais code. Tweet

Refactoriser le code Ruby on Rails

Eh bien, je suis ici pour vous dire: il est normal d’écrire du mauvais code. Parfois, un mauvais code Rails est plus facile à refactoriser en beau code qu'une solution mal pensée implémentée dans un temps limité.



C'est le processus de refactoring de Rails que j'aime suivre pour éliminer les problèmes de mes horribles solutions de pansement:



Ce processus de refactoring de Ruby on Rails est celui que je suis pour résoudre les problèmes de Rails.

Pour une autre perspective, voici le Journal de validation Git pour une fonctionnalité qui a été refactorisée étape par étape:



Ce journal montre un refactor Rails qui a été effectué étape par étape.

Et voici un autre article intéressant sur refactoring à grande échelle d'un collègue du réseau ApeeScape.



Voyons comment cela se fait.

Les vues

Étape 1. Commencez dans les vues



Disons que nous commençons un ticket pour une nouvelle fonctionnalité. Le client nous dit: 'Les visiteurs doivent pouvoir afficher une liste des projets actifs sur la page d'accueil.'

Ce ticket nécessite un changement visible, donc un endroit raisonnable pour commencer le travail serait dans les vues. Le problème est simple et nous avons tous été formés pour le résoudre plusieurs fois. Je vais le résoudre La mauvaise direction et montrer comment refactoriser ma solution dans ses domaines appropriés. Résoudre un problème La mauvaise direction peut nous aider à surmonter le problème de ne pas connaître la bonne solution.



Pour commencer, supposons que nous ayons un modèle appelé Project avec un attribut booléen appelé active. Nous voulons obtenir une liste de tous Projects où active est égal à true, donc nous pouvons utiliser Project.where(active: true), et boucler dessus avec un each bloquer.

app/views/pages/welcome.haml: %ul.projects - Project.where(active: true).each do |project| %li.project= link_to project_path(project), project.name

Je sais ce que vous dites: 'Cela ne passerait jamais une révision de code' ou 'Mon client me licencierait sûrement pour cela.' Oui, cette solution rompt la séparation des problèmes Modèle-Vue-Contrôleur, cela peut entraîner des appels de base de données parasites difficiles à tracer et il peut devenir difficile à maintenir à l'avenir. Mais considérez la valeur de le faire La mauvaise direction :



  1. Vous pouvez obtenir ce changement lors de la mise en scène en moins de 15 minutes.
  2. S'il est laissé dedans, ce bloc est facile à mettre en cache.
  3. La résolution de ce problème de Rails est simple (peut être confiée à un développeur junior).

Étape 2. Partiels

Après l'avoir fait La mauvaise direction , Je me sens mal dans ma peau et je veux isoler mon mauvais code. Si ce changement n'était clairement qu'une préoccupation du calque Vue, je pourrais refactoriser ma honte en un partiel.

app/views/pages/welcome.haml: = render :partial => 'shared/projects_list' app/views/shared/projects_list.haml: %ul.projects - Project.where(active: true).each do |project| %li.project= link_to project_path(project), project.name

C’est un peu mieux. De toute évidence, nous faisons toujours l'erreur d'une requête de modèle dans une vue, mais au moins lorsqu'un responsable arrive plus tard et voit mon horrible partiel, il aura un moyen simple de s'attaquer à ce problème de code Rails en particulier. Corriger quelque chose de évidemment stupide est toujours plus facile que de corriger une abstraction boguée mal implémentée.

Corriger quelque chose de évidemment stupide est toujours plus facile que de corriger une abstraction boguée mal implémentée. Tweet

Étape 3. Aides

Les Helpers in Rails sont un moyen de créer un DSL (langage spécifique au domaine) pour une section de vos vues. Vous devez réécrire votre code en utilisant content_tag au lieu de hameau ou HTML, mais vous bénéficiez de la possibilité de manipuler les structures de données sans que les autres développeurs vous regardent pendant 15 lignes de code View non imprimable.

Si je devais utiliser des helpers ici, je refactoriserais probablement le li marque.

app/views/shared/projects_list.haml: %ul.projects - Project.where(active: true).each do |project| = project_list_item(project) app/helpers/projects_helper.rb: def project_list_item(project) content_tag(:li, :class => 'project') do link_to project_path(project), project.name end end

Les contrôleurs

Étape 4. Déplacez-le vers les contrôleurs

Peut-être que votre code horrible n'est pas seulement un problème de vue. Si votre code sent toujours, recherchez les requêtes que vous pouvez passer des vues aux contrôleurs.

app/views/shared/projects_list.haml: %ul.projects - @projects_list.each do |project| = project_list_item(project) app/controllers/pages_controller.rb: def welcome @projects = Project.where(active: true) end

Étape 5. Filtres du contrôleur

La raison la plus évidente de déplacer du code dans un contrôleur before_filter ou after_filter est pour le code que vous avez dupliqué dans plusieurs actions du contrôleur. Vous pouvez également déplacer le code dans un Filtre contrôleur si vous souhaitez séparer le but de l'action du contrôleur des exigences de vos vues.

app/controllers/pages_controller.rb: before_filter :projects_list def welcome end def projects_list @projects = Project.where(active:true) end

Étape 6. Contrôleur d'application

Supposons que vous ayez besoin que votre code apparaisse sur chaque page, ou que vous souhaitiez rendre les fonctions d'assistance du contrôleur disponibles pour tous les contrôleurs, vous pouvez déplacer votre fonction dans ApplicationController. Si les modifications sont globales, vous pouvez également modifier la disposition de votre application.

app/controllers/pages_controller.rb: def welcome end app/views/layouts/application.haml: %ul.projects - projects_list.each do |project| = project_list_item(project) app/controllers/application_controller.rb: before_filter :projects_list def projects_list @projects = Project.where(active: true) end

Les modèles

Étape 7. Refactoring au modèle

Comme le dit la devise MVC: Modèle gras, contrôleurs skinny et vues stupides . Nous sommes censés refactoriser tout ce que nous pouvons dans le modèle, et il est vrai que les fonctionnalités les plus complexes deviendront éventuellement des associations de modèles et des méthodes de modèle. Nous devons toujours éviter de mettre en forme / visualiser des choses dans le modèle, mais la transformation de données en d'autres types de données est autorisée. Dans ce cas, la meilleure chose à refactoriser dans le modèle serait le where(active: true) clause, que nous pouvons transformer en champ d'application. Utiliser une portée est utile non seulement parce que cela rend l'appel plus joli, mais si nous décidons d'ajouter un attribut comme delete ou outdated, nous pouvons modifier cette portée au lieu de traquer tous nos where clauses.

app/controllers/application_controller.rb: before_filter :projects_list def projects_list @projects = Project.active end app/models/project.rb: scope :active, where(active: true)

Étape 8. Filtres de modèle

Nous n’avons pas d’utilisation particulière pour un modèle before_save ou after_save filters dans ce cas, mais l'étape suivante que je prends habituellement est de déplacer les fonctionnalités des contrôleurs et des méthodes de modèle vers les filtres de modèle.

Supposons que nous ayons un autre attribut, num_views. Si num_views > 50, le projet devient inactif. Nous pourrions résoudre ce problème dans la vue, mais apporter des modifications à la base de données dans une vue est inapproprié. Nous pourrions le résoudre dans le contrôleur, mais nos contrôleurs doivent être aussi minces que possible! Nous pouvons le résoudre facilement dans le modèle.

s corp contre c corp contre llc
app/models/project.rb: before_save :deactivate_if_over_num_views def deactivate_if_over_num_views if num_views > 50 self.active = false fi end

Remarque: évitez d'appeler self.save dans un filtre de modèle, car cela provoque des événements de sauvegarde récursifs, et la couche de manipulation de base de données de votre application doit de toute façon être le contrôleur.

Étape 9. Bibliothèques

Parfois, votre fonctionnalité est suffisamment volumineuse pour justifier sa propre bibliothèque. Vous souhaiterez peut-être le déplacer dans un fichier de bibliothèque, car il est réutilisé dans de nombreux endroits, ou il est suffisamment volumineux pour que vous souhaitiez en développer séparément.

Vous pouvez stocker des fichiers de bibliothèque dans le lib / répertoire, mais au fur et à mesure qu'ils grandissent, vous pouvez les transférer dans un véritable RubyGem ! Un avantage majeur du déplacement de votre code dans une bibliothèque est que vous pouvez tester la bibliothèque séparément de votre modèle.

Quoi qu'il en soit, dans le cas d'une liste de projets, nous pourrions justifier le déplacement du scope :active appel depuis le Project model dans un fichier de bibliothèque et le ramener dans Ruby:

app/models/project.rb: class Project 50 self.active = false end end end

Remarque: le self.included est appelée lorsqu'une classe de modèle Rails est chargée et transmet la portée de la classe en tant que variable k.

Conclusion

Dans ce didacticiel de refactorisation Ruby on Rails, nous avons pris moins de 15 minutes et mis en œuvre une solution et l'avons mise en préparation pour les tests utilisateur, prête à être acceptée dans l'ensemble de fonctionnalités ou supprimée. À la fin du processus de refactorisation, nous avons un morceau de code qui définit un cadre pour la mise en œuvre d'éléments pouvant être listés et activés sur plusieurs modèles qui passeraient même le processus d'examen le plus strict.

Dans votre propre processus de refactoring de Rails, n'hésitez pas à sauter quelques étapes dans le pipeline si vous êtes sûr de le faire (par exemple, passer de la vue au contrôleur ou du contrôleur au modèle). Gardez simplement à l'esprit que le flux de code va de la vue au modèle.

N'ayez pas peur de paraître stupide. Ce qui distingue les langages modernes des anciennes applications de rendu de modèles CGI, ce n’est pas que nous faisons tout Le droit chemin à chaque fois - c'est que nous prenons le temps de refactoriser, réutiliser et partager nos efforts.

En relation: Timestamp Truncation: A Ruby on Rails ActiveRecord Tale

Défier la censure Internet: Comment ai-je créé un site Web pour collecter des Weibo approuvés

Interface Web

Défier la censure Internet: Comment ai-je créé un site Web pour collecter des Weibo approuvés
Ouvrir la voie à l'achat - Meilleures pratiques eCommerce UX

Ouvrir la voie à l'achat - Meilleures pratiques eCommerce UX

Conception Ux

Articles Populaires
Explorer la fonctionnalité Get & Transform d'Excel
Explorer la fonctionnalité Get & Transform d'Excel
Comment aborder les wrappers pour les propriétés Swift
Comment aborder les wrappers pour les propriétés Swift
ApeeScape s'associe à Guidant Global pour offrir un accès à la demande au réseau Elite de pigistes
ApeeScape s'associe à Guidant Global pour offrir un accès à la demande au réseau Elite de pigistes
Tutoriel Apache Spark Streaming: Identifier les hashtags Twitter tendances
Tutoriel Apache Spark Streaming: Identifier les hashtags Twitter tendances
Conception accessible vs conception inclusive (avec infographie)
Conception accessible vs conception inclusive (avec infographie)
 
L'intégration continue d'iOS avec le serveur Xcode expliquée
L'intégration continue d'iOS avec le serveur Xcode expliquée
Meilleurs éditeurs de programmation? Une bataille sans fin sans vainqueur clair
Meilleurs éditeurs de programmation? Une bataille sans fin sans vainqueur clair
Comment GWT déverrouille la réalité augmentée dans votre navigateur
Comment GWT déverrouille la réalité augmentée dans votre navigateur
Webpack ou Browserify & Gulp: quel est le meilleur?
Webpack ou Browserify & Gulp: quel est le meilleur?
Business Analyst - Stratégie & Analytics
Business Analyst - Stratégie & Analytics
Articles Populaires
  • applications de rencontres les plus populaires 2017
  • comment écrire un langage de programmation
  • dans quelle langue est écrit windows
  • calculateur de salaire employé à entrepreneur
  • société s vs société c
  • lois de la gestalt de l'organisation perceptive
Catégories
  • Science Des Données Et Bases De Données
  • Conception Mobile
  • Design De Marque
  • Personnes Et Équipes Produit
  • © 2022 | Tous Les Droits Sont Réservés

    portaldacalheta.pt