From 081e9077f7d0acbd22295c0680014160419b4e80 Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Thu, 22 May 2025 10:34:19 +0200 Subject: [PATCH] Script to reset card ids --- script/reset_cards_ids.rb | 165 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 script/reset_cards_ids.rb diff --git a/script/reset_cards_ids.rb b/script/reset_cards_ids.rb new file mode 100644 index 000000000..19305b5f2 --- /dev/null +++ b/script/reset_cards_ids.rb @@ -0,0 +1,165 @@ +#!/usr/bin/env ruby + +require_relative "../config/environment" + +ApplicationRecord.with_each_tenant do |tenant| + id_mapping = {} + + puts "Processing tenant: #{tenant}" + + # Disable foreign key constraints + ApplicationRecord.connection.execute("PRAGMA foreign_keys = OFF;") + + begin + # Get all cards ordered by ID + cards = Card.order(:id).to_a + + # Create mapping of old IDs to new IDs + cards.each_with_index do |card, index| + id_mapping[card.id] = index + 1 + end + + # Update foreign keys in related tables + puts "Updating foreign keys in related tables..." + + # Update assignments table + Assignment.where.not(card_id: nil).find_each do |assignment| + if id_mapping[assignment.card_id] + assignment.update_column(:card_id, id_mapping[assignment.card_id]) + end + end + + # Update card_engagements table + Card::Engagement.where.not(card_id: nil).find_each do |engagement| + if id_mapping[engagement.card_id] + engagement.update_column(:card_id, id_mapping[engagement.card_id]) + end + end + + # Update card_goldnesses table + Card::Goldness.where.not(card_id: nil).find_each do |goldness| + if id_mapping[goldness.card_id] + goldness.update_column(:card_id, id_mapping[goldness.card_id]) + end + end + + # Update closures table + Closure.where.not(card_id: nil).find_each do |closure| + if id_mapping[closure.card_id] + closure.update_column(:card_id, id_mapping[closure.card_id]) + end + end + + # Update comments table + Comment.where.not(card_id: nil).find_each do |comment| + if id_mapping[comment.card_id] + comment.update_column(:card_id, id_mapping[comment.card_id]) + end + end + + # Update pins table + Pin.where.not(card_id: nil).find_each do |pin| + if id_mapping[pin.card_id] + pin.update_column(:card_id, id_mapping[pin.card_id]) + end + end + + # Update taggings table + Tagging.where.not(card_id: nil).find_each do |tagging| + if id_mapping[tagging.card_id] + tagging.update_column(:card_id, id_mapping[tagging.card_id]) + end + end + + # Update watches table + Watch.where.not(card_id: nil).find_each do |watch| + if id_mapping[watch.card_id] + watch.update_column(:card_id, id_mapping[watch.card_id]) + end + end + + # Update events table (polymorphic relationship) + Event.where(eventable_type: "Card").find_each do |event| + if id_mapping[event.eventable_id] + event.update_column(:eventable_id, id_mapping[event.eventable_id]) + end + end + + # Update mentions table (polymorphic relationship) + Mention.where(source_type: "Card").find_each do |mention| + if id_mapping[mention.source_id] + mention.update_column(:source_id, id_mapping[mention.source_id]) + end + end + + # Update notifications table (polymorphic relationship) + Notification.where(source_type: "Card").find_each do |notification| + if id_mapping[notification.source_id] + notification.update_column(:source_id, id_mapping[notification.source_id]) + end + end + + # Update action_text_markdowns table (polymorphic relationship) + ActionText::Markdown.where(record_type: "Card").find_each do |markdown| + if id_mapping[markdown.record_id] + markdown.update_column(:record_id, id_mapping[markdown.record_id]) + end + end + + # Reset the cards table IDs + puts "Resetting card IDs..." + cards.each do |card| + new_id = id_mapping[card.id] + # Use direct SQL to update the ID to avoid ActiveRecord validations + ApplicationRecord.connection.execute("UPDATE cards SET id = #{new_id} WHERE id = #{card.id}") + end + + # Reset the SQLite sequence for the cards table + ApplicationRecord.connection.execute("DELETE FROM sqlite_sequence WHERE name = 'cards'") + max_id = Card.maximum(:id) || 0 + ApplicationRecord.connection.execute("INSERT INTO sqlite_sequence (name, seq) VALUES ('cards', #{max_id})") + + puts "Card IDs have been reset successfully!" + rescue => e + puts "Error: #{e.message}" + puts e.backtrace + ensure + # Re-enable foreign key constraints + ApplicationRecord.connection.execute("PRAGMA foreign_keys = ON;") + end + + Card.find_each do |card| + description = card.description.content.dup + + description.gsub!(/cards\/(\d+)\)/) do |match| + old_id = $1.to_i + new_id = id_mapping[old_id] + + new_id ? "cards/#{new_id})" : match + end + + if description != card.description.content + puts "Updating links in card #{card.id}" + card.update!(description: description) + end + end + + Comment.find_each do |comment| + body = comment.body.content.dup + + body.gsub!(/cards\/(\d+)\)/) do |match| + old_id = $1.to_i + new_id = id_mapping[old_id] + new_id ? "cards/#{new_id})" : match + end + + if body != comment.body.content + puts "Updating links in comment #{comment.id}" + comment.update!(body: body) + end + end + + # Output the mapping of old IDs to new IDs + puts "\nMapping of old IDs to new IDs:" + puts id_mapping.inspect +end