[RUBY] Rails: comment bien écrire une tâche de râteau

Bon sentiment = les deux points suivants

  1. Facile à tester
  1. (Dans une certaine mesure) le style d'écriture peut être unifié parmi les ingénieurs

etc

code

lib/tasks/issue_6885.rake


require_relative 'helpers/all_user_name_update_helper.rb'

namespace :issue_6885 do

  desc 'Ceci est un échantillon'
  task all_user_name_update: :environment do
    helper = AllUserNameUpdateHelper.new

    helper.main
  end
end

lib/tasks/helpers/all_user_name_update_helper.rb


require_relative 'rake_helper_template'

class AllUserNameUpdateHelper < RakeHelperTemplate
  NEW_NAME = 'bar'

  def main
    template do |logger|
      all_users = get_all_user
      logger.info("Nombre d'utilisateurs cibles: #{all_users.size}")

      if all_users.blank?
        logger.info('Le processus se termine car le nombre d'utilisateurs cibles était de 0.')
        return
      end

      all_users.each { |user| update_name(user, NEW_NAME) }
    end
  end

  private

  def get_all_user
    User.all
  end

  def update_name(user, new_name)
    user.update!(name: new_name)
    user
  end
end

lib/tasks/helpers/rake_helper_template.rb


class RakeHelperTemplate
  #Effectuer également une sortie standard
  def make_logger(log_file_path)
    logger = ActiveSupport::Logger.new(log_file_path)
    stdout_logger = ActiveSupport::Logger.new(STDOUT)
    broadcast_logger = ActiveSupport::Logger.broadcast(stdout_logger)
    logger.extend(broadcast_logger)
    logger.formatter = Logger::Formatter.new
    logger
  end

  #Rendez le nom du fichier journal identique au nom de la tâche (remplacez-le car il vaut mieux ne pas utiliser de deux-points)
  #Les cas appelés depuis l'exécution de la tâche rake:spec) doit être pris en considération
  def make_log_file_path
    task_name = Rake.try(:application)&.top_level_tasks&.[](0)&.gsub(':','_') || Rails.env
    log_file_name = "#{task_name}.log"
    Rails.root.join('log', log_file_name)
  end

  def template
    log_file_path = make_log_file_path

    #Assurez-vous de dryrun sauf si vous passez explicitement la chaîne false
    is_dryrun = ENV['is_dryrun'] != 'false'

    logger = make_logger(log_file_path)
    logger.info("Start. is_dryrun: #{is_dryrun}")

    ActiveRecord::Base.transaction do
      yield(logger)
      raise ActiveRecord::Rollback if is_dryrun
    end

    logger.info("Finish. log_file_path: #{log_file_path}")
  end
end

Exemple d'exécution

Lors d'un essai à sec


$ is_dryrun=false bundle exec rake issue_6885:all_user_name_update
I, [2020-09-27T13:33:27.229764 #13040]  INFO -- : Start. is_dryrun: true
I, [2020-09-27T13:33:27.556890 #13040]  INFO -- :Nombre d'utilisateurs cibles: 1
I, [2020-09-27T13:33:27.755933 #13040]  INFO -- : Finish. log_file_path: /app/log/issue_6885_all_user_name_update.log 

point

  1. Le fichier .rake appelle uniquement la classe d'assistance, le DSL de rake? J'ai essayé de tester la méthode de la classe que j'ai l'habitude d'écrire sans me soucier de la manière habituelle
  1. Utilisez yield pour standardiser dryrun et logger (une partie de) afin que vous n'ayez pas à les définir à chaque fois que vous créez une tâche de râteau.

Une fois que vous avez un modèle, vous pouvez vous concentrer sur ce que vous voulez faire comme all_user_name_update_helper.rb! (^ ○ ^)

Impressions

Recommended Posts

Rails: comment bien écrire une tâche de râteau
Comment écrire des rails
[Rails] Comment écrire lors de la création d'une sous-requête
Comment écrire des graines de Rails
Comment écrire le routage Rails
Comment écrire une recherche de comparaison de dates dans Rails
[Rails] Comment écrire la gestion des exceptions?
Comment écrire une migration du type Rails datetime au type date
[Basique] Comment écrire un auto-apprentissage Dockerfile ②
Comment insérer une vidéo dans Rails
[Introduction à Java] Comment écrire un programme Java
[rails] Comment créer un modèle partiel
[SpringBoot] Comment écrire un test de contrôleur
[Rails] Comment créer un graphique à l'aide de lazy_high_charts
Comment exécuter une tâche djUnit dans Ant
Comment désinstaller Rails
Comment écrire docker-compose
Comment écrire Mockito
Comment implémenter une fonctionnalité similaire dans Rails
Comment créer facilement un pull-down avec des rails
[Rails] Comment créer un bouton de partage Twitter
Comment écrire un fichier de migration
[Rails] Mettre en œuvre la tâche de râteau
Comment implémenter une fonctionnalité intéressante dans Ajax avec Rails
[Ruby on Rails] Comment écrire enum en japonais
Comment écrire un test unitaire pour Spring Boot 2
Comment supprimer un objet new_record construit avec Rails
java: Comment écrire une liste de types génériques [Note]
Comment générer manuellement un JWT avec Knock in Rails
[Comment insérer une vidéo dans un hameau avec Rails]
[Rails 6] Comment définir une image d'arrière-plan dans Rails [CSS]
[Rails] Comment charger JavaScript dans une vue spécifique
Comment écrire un mod de base dans Minecraft Forge 1.15.2
[rails] Comment publier des images
Comment écrire du bon code
[Rails] Comment utiliser enum
[Rails] Comment utiliser enum
Comment rédiger un commentaire java
Comment laisser un commentaire
Comment lire les itinéraires des rails
Définissons une tâche Rake.
[Refactoring] Comment écrire le routage
Comment utiliser la jonction de rails
Comment écrire Junit 5 organisé
Comment terminer le serveur de rails
[Rails] Comment utiliser la validation
Pour écrire un programme orienté utilisateur (1)