2017-09-14 1 views
0

Je n'exécutais pas de validations, et j'ai donc des doublons dans mon db. Maintenant, j'ai besoin de supprimer l'enregistrement qui est plus ancien que le dernier enregistrement. Quelle est la meilleure façon de le faire dans Ruby?Supprimer activeecord row qui est plus ancien que l'enregistrement le plus récent

Je le fais pour trouver les dups d'un seul magasin:

customers = Shop.find(105).customers 
emails = customers.pluck(:shop_id, :id, :customer_id, :email, :created_at, :credit_amount) 
gemails = emails.group_by{ |shop_id, id, customer_id, email, created_at, credit_amount_to_f| customer_id } 
gemails.delete_if{ |_, v| v.compact.size <= 1 } 

gemails retourne les dups avec le customer_id comme la clé.

je peux alors trouver le plus récent record pour le premier doublon comme celui-ci:

Customer.where(customer_id: gemails.keys[0]).order("updated_at").last 

Comment puis-je me débarrasser de tous les enregistrements qui partagent la customer_id qui ne sont pas la dernière?

Merci

Répondre

0

D'abord, vous pouvez trouver l'identifiant de l'ordre que vous ne souhaitez pas supprimer (le plus récent) - ce qui est similaire à ce que vous avez déjà, mais il est plus efficace d'utiliser :desc pour commander les enregistrements d'une manière que le plus récent (la plus haute date) est tout d'abord, de cette façon vous pouvez utiliser limit(1) et .first:

customer_id = gemails.keys[0] 
first_order_id = Customer.where(customer_id: customer_id).order(updated_at: :desc).limit(1).first.id 

vous pouvez supprimer toutes les commandes de client qui ne partagent pas le même numéro de commande:

Customer.where(customer_id: customer_id).where.not(id: first_order_id).delete_all 

Vous devriez faire une copie de vos données avant de faire ce genre de choses - Je détesterais toute erreur que j'ai faite pour vous faire perdre des données.

C'est également le genre de chose qui pourrait être utile pour les tests ou le nettoyage ponctuel des données, mais vous devriez utiliser des validations dans vos modèles pour empêcher les données d'atteindre cet état en premier lieu.