How to Refactor Your Rails App With Service Objects

Comment refactoriser votre application Rails avec des objets de service

À mesure que la complexité des applications Rails augmente, il devient crucial de maintenir un code propre, lisible et maintenable. Une approche efficace pour y parvenir consiste à refactoriser votre base de code à l’aide d’objets de service. Les objets de service aident à extraire la logique métier complexe des modèles ou des contrôleurs dans des classes distinctes, favorisant ainsi une meilleure organisation, testabilité et réutilisation. Dans cet article, nous explorerons le processus de refactorisation d'une application Rails avec des objets de service, en fournissant un exemple pratique pour démontrer leurs avantages.

Identifier le problème : Pour commencer le processus de refactorisation, commencez par identifier une section de code qui contient une logique complexe ou viole le principe de responsabilité unique (SRP). Supposons que nous ayons une application Rails avec un UserController qui gère la création, la validation et la notification des utilisateurs.

Extraction d'un objet de service : pour refactoriser ce code, extrayez la logique complexe liée à la création et à la notification des utilisateurs dans un objet de service distinct. Créez un nouveau fichier appelé user_creation_service.rb dans le répertoire app/services. Voici un exemple de ce à quoi pourrait ressembler l'objet de service :

#app/services/user_creation_service.rb

classe UserCreationService

  def initialiser (user_params)

    @user_params = utilisateur_params

  fin

  def créer_utilisateur

    utilisateur = Utilisateur.new (@user_params)

    si utilisateur.save

      envoyer_notification (utilisateur)

      vrai

    autre

      FAUX

    fin

  fin

  privé

  def send_notification (utilisateur)

    # Logique pour envoyer une notification à l'utilisateur

  fin

fin

Mise à jour du UserController : Dans le UserController, remplacez la logique complexe par un appel à l'objet de service. Voici un exemple de la façon dont il pourrait être mis à jour :

#app/controllers/users_controller.rb

classe UsersController < ApplicationController

  créer par défaut

    user_service = UserCreationService.new (user_params)

    si user_service.create_user

      redirect_to root_path, remarque : "Utilisateur créé avec succès !"

    autre

      rendu :nouveau

    fin

  fin

  privé

  def user_params

    params.require(:user).permit(:name, :email, :password)

  fin

fin

Test de l'objet de service : Les objets de service peuvent être facilement testés de manière isolée, garantissant ainsi l'exactitude de la logique extraite. Écrivez des tests pour la classe UserCreationService, en vous moquant des dépendances si nécessaire. Par exemple:

#spec/services/user_creation_service_spec.rb

nécessite 'rails_helper'

RSpec.describe UserCreationService faire

  décrire '#create_user' faire

    il "crée un utilisateur et envoie une notification"

      user_params = { nom : 'John Doe', email : '[email protected]', mot de passe : 'mot de passe' }

      user_service = UserCreationService.new (user_params)

      s'attendre à ce que (user_service.create_user) soit vrai

      attendre(Notification).to have_received(:send).with(instance_of(Utilisateur))

    fin

    il "renvoie faux si la création de l'utilisateur échoue"

      Cas d’échec du test #

    fin

  fin

fin

Conclusion: 

En refactorisant votre Application Rails avec les objets de service, vous pouvez séparer efficacement une logique métier complexe, améliorer l'organisation du code et améliorer la testabilité. L'exemple pratique fourni montre le processus d'extraction de la logique de création et de notification d'utilisateur dans un objet de service, ce qui donne un code plus propre et plus maintenable. Profitez de la puissance des objets de service pour rationaliser votre application Rails et profitez des avantages d'une base de code modulaire et évolutive.



Articles Similaires

Laissez un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

fr_FRFrench