[RUBY] Empêcher les opérations! Méthode de mise à jour manuelle sûre des données pour Rails utilisant des transactions

Vous devez mettre à jour manuellement les données en cas d'incohérence des données ou lorsque vous souhaitez modifier la valeur d'une colonne existante. Les mises à jour manuelles doivent être effectuées avec prudence, car vous travaillerez directement avec les données de production.

Cette fois, je vais vous montrer comment mettre à jour en toute sécurité et manuellement les données de l'application Ruby on Rails.

Méthode de mise à jour manuelle commune des données

Par exemple, supposons qu'une incohérence de données se produise entre l'événement et l'entrée liés de manière un-à-plusieurs et qu'il devienne nécessaire de changer manuellement l'entrée liée à ʻevent_id = 10 en ʻevent_id = 11. Je vais.

Une solution de contournement courante consiste à mettre à jour manuellement avec la console rails comme suit:

#Confirmation avant la mise à jour
Entry.where(event_id: 10).count
=> 5
Entry.where(event_id: 11).count
=> 0

#Mettre à jour le travail
Entry.where(event_id: 10).update_all(event_id: 11)

#Confirmation après mise à jour
Entry.where(event_id: 10).count
=> 0
Entry.where(event_id: 11).count
=> 5

Lors de la mise à jour des données avec rails console, je pense que le processus" d'exécution de commandes dans l'environnement de développement et de confirmation qu'il n'y a pas d'erreurs avant d'effectuer le travail de production "est souvent adopté.

Méthode présentée ici: mettre à jour les données dans une transaction

Si le nombre de données est petit ou si la mise à jour des données n'est pas compliquée, la mise à jour manuelle à l'aide de rails console convient. Cependant, ** Lors de la mise à jour de données compliquées, je souhaite pouvoir revenir à l'état d'avant la mise à jour s'il y a un problème **. Dans un tel cas, il est recommandé de mettre à jour les données à l'aide de transactions.

Insérez la mise à jour des données dans nom du modèle.transaction afin que la restauration puisse être effectuée en cas de problèmes.

La restauration est effectuée lorsqu'une exception se produit dans la transaction. Vous pouvez utiliser rise ActiveRecord :: Rollback pour déclencher intentionnellement une exception, ce qui entraîne une annulation.

Le script qui exécute la mise à jour manuelle des données introduite précédemment dans une transaction est le suivant.

# app/script/maintenance/20201103_fix_envent_id.rb

ActiveRecord::Base.transaction do

  # update_Empêcher la mise à jour de l'horodatage at
  Entry.record_timestamps = false

  puts "Before event_id = 10: #{Entry.where(event_id: 10).count}"
  puts "Before event_id = 11: #{Entry.where(event_id: 11).count}"

  Entry.where(event_id: 10).each do |entry|
    begin
      entry.update!(event_id: 11)
    rescue => e
      puts 'échec de la mise à jour de l'entrée'
      puts e
      puts "entry.id: #{entry.id}"
    end
  end

  puts "After entry_id = 10: #{Entry.where(event_id: 10).count}"
  puts "After entry_id = 11: #{Entry.where(event_id: 11).count}"

  print "Are you sure?(yes/no) > "
  answer = gets.strip
  if answer == "yes"
    puts "committed"
  else
    puts "rollback"
    raise ActiveRecord::Rollback
  end

  #Puisque je l'ai mis à faux au début, retournez-le à l'original (vrai)
  Entry.record_timestamps = true
end

Le but du script est qu'il attend l'entrée de la commande en utilisant gets une fois la mise à jour des données terminée. Si vous entrez un caractère autre que «yes», «raise ActiveRecord :: Rollback» sera appelé et le rollback sera effectué.

En sortant l'état de l'enregistrement le cas échéant, par exemple la manière dont le nombre d'enregistrements a changé avant et après la mise à jour des données, vous pouvez vérifier en toute sécurité qu'il n'y a pas de problèmes avant de terminer la mise à jour des données.

Exécutez le script avec rails runner. Cette fois, j'exécute «rails runner» contre l'environnement de développement. Ajoutez l'option -e production si vous souhaitez l'exécuter dans un environnement de production.

$ rails runner app/script/maintenance/20201103_fix_envent_id.rb

Before Entry.where(event_id: 10).count: 5
Before Entry.where(event_id: 11).count: 0
After Entry.where(event_id: 10).count: 0
After Entry.where(event_id: 11).count: 5
Are you sure?(yes/no) > yes
committed

Référence: Résumé des méthodes de mise à jour des applications Rails

Les applications Rails ont plusieurs méthodes pour mettre à jour les données. Les différences entre les méthodes typiques sont les suivantes.

Méthode Validation Rappeler updated_mise à jour de à S'il faut mettre à jour plusieurs colonnes
update
update_attributes
update_attribute × ×
update_all × × ×
update_columns × × ×
update_column × × × ×

** Si vous voulez juste changer la valeur de l'enregistrement, utilisez ʻupdate_columns, et si vous voulez mettre à jour les données tout en assurant la cohérence, utilisez ʻupdate **.

De plus, lors de la mise à jour des données avec ʻupdate, si vous avez des problèmes si ʻupdated_at de l'enregistrement à mettre à jour change, il est préférable de définirrecord_timestamps sur false avant la mise à jour. N'oubliez pas de remettre record_timestamps à true après la mise à jour.

Sommaire

Ceci conclut l'introduction de méthodes de mise à jour des données utilisant des transactions.

--Si vous souhaitez mettre à jour les données en toute sécurité, il est recommandé d'exécuter le script inclus dans la transaction avec rails runner.

Je fais Twitter (@ nishina555). J'espère que vous me suivrez!

référence

Recommended Posts

Empêcher les opérations! Méthode de mise à jour manuelle sûre des données pour Rails utilisant des transactions
[Rails] Comment empêcher la transition d'écran
[Rails] Comment télécharger des images à l'aide de Carrierwave
Pour implémenter la publication d'images à l'aide de rails
[Rails] Comment télécharger plusieurs images à l'aide de Carrierwave
Comment écrire des rails
Comment désinstaller Rails
Comment générer manuellement un JWT avec Knock in Rails
Comment définir des variables d'environnement lors de l'utilisation de Payjp avec Rails
[Rails] Comment utiliser enum
Comment lire les itinéraires des rails
Comment utiliser la jonction de rails
Comment définir et décrire des variables d'environnement à l'aide de Rails zsh
Comment mettre à jour avec activerecord-import
Comment déployer jQuery dans les applications Rails à l'aide de Webpacker
Comment terminer le serveur de rails
Comment écrire des graines de Rails
[Rails] Comment utiliser la validation
[Rails] Comment désactiver les turbolinks
[Rails] Comment utiliser authenticate_user!
[Rails] Comment mettre en œuvre le scraping
[Rails] Comment faire des graines
Comment écrire le routage Rails
[Rails] Comment installer simple_calendar
[Rails] Comment installer reCAPTCHA
[Rails] Comment utiliser Scope
Comment autoriser à l'aide de graphql-ruby
Comment contrôler les transactions dans Spring Boot sans utiliser @Transactional
Comment empêcher la saisie de dates passées dans les formulaires Rails
[Rails 6] Comment créer un écran de saisie de formulaire dynamique à l'aide de cocoon
[Rails] Comment télécharger des images sur AWS S3 à l'aide de Carrierwave et de fog-aws
[Rails] Comment télécharger des images sur AWS S3 à l'aide de refile et refile-s3
[Rails 5] Comment afficher l'écran de changement de mot de passe lors de l'utilisation de l'appareil
[rails6.0.0] Comment enregistrer des images en utilisant Active Storage au format assistant
[Rails] Comment utiliser la "devise" des gemmes
[Rails] Comment utiliser l'appareil (Remarque)
[Rails] Comment utiliser les messages flash
[rails] Comment afficher les informations de base de données
Comment utiliser Ruby on Rails
Comment déployer Bootstrap sur Rails
[Rails] Comment accélérer la composition de docker
[Rails] Comment ajouter de nouvelles pages
[Rails] Comment écrire la gestion des exceptions?
[Rails] Comment installer ImageMagick (RMajick)
[Rails] Comment installer Font Awesome
[Rails] Comment utiliser Active Storage
Comment installer jQuery dans Rails 6
[Rails] Comment mettre en œuvre le classement par étoiles