Я поделюсь здесь скриптом. Имейте в виду, что я не уверен, что это лучший подход к решению проблемы. Скрипт нужно запускать после того, как начнут создаваться дубликаты тем в результате изменения доменного имени. Поскольку темы не будут созданы, пока пользователи не начнут посещать ваши записи блога по новому домену, вам, вероятно, придется запускать скрипт несколько раз, чтобы обработать все темы. Обязательно замените old.domain.com в первой строке скрипта на реальный домен, на котором ранее находился ваш блог.
# Сначала выполните это:
original_embeds = TopicEmbed.where("embed_url LIKE ?", "%old.domain.com%")
# Затем:
original_embeds.each do |original_embed|
original_topic = Topic.find(original_embed.topic_id)
if (original_topic && original_topic.title)
possible_dups = Topic.where(title: original_topic.title).order(:created_at)
if possible_dups.length === 2
new_embed = TopicEmbed.find_by(topic_id: possible_dups.last.id)
new_embed_url = new_embed.embed_url
puts "Удаление записи TopicEmbed: #{new_embed.id}, Тема: #{new_embed.topic_id}"
new_embed.destroy
puts "Обновление записи TopicEmbed: #{original_embed.id}, Новый embed_url: #{new_embed_url}"
original_embed.update(embed_url: new_embed_url)
end
end
end
Чтобы запустить скрипт, откройте консоль Rails вашего сайта, скопируйте первую строку скрипта в консоль и выполните её. Это присвоит переменной original_embeds массив записей TopicEmbed. После этого вы можете скопировать остальную часть скрипта в консоль и запустить его.
Для безопасности перед запуском скрипта создайте резервную копию базы данных вашего сайта. Также рекомендуется выполнить тестовый прогон скрипта, который не вносит никаких изменений. Для этого используйте следующий код:
original_embeds.each do |original_embed|
original_topic = Topic.find(original_embed.topic_id)
if (original_topic && original_topic.title)
possible_dups = Topic.where(title: original_topic.title).order(:created_at)
if possible_dups.length === 2
new_embed = TopicEmbed.find_by(topic_id: possible_dups.last.id)
new_embed_url = new_embed.embed_url
puts "(Тестовый прогон) Удаление записи TopicEmbed: #{new_embed.id}, Тема: #{new_embed.topic_id}"
#new_embed.destroy
puts "(Тестовый прогон) Обновление записи TopicEmbed: #{original_embed.id}, Новый embed_url: #{new_embed_url}"
#original_embed.update(embed_url: new_embed_url)
end
end
end
Убедитесь, что вывод выглядит разумным, прежде чем раскомментировать строки, которые вносят фактические изменения в вашу базу данных.
Что делает скрипт:
-
переменная original_embeds получает все записи TopicEmbed, соответствующие старому домену вашего блога
-
для каждой записи из original_embeds скрипт пытается найти тему с дублирующимся заголовком (новый дублирующийся встраиваемый элемент)
-
если найдена дублирующаяся тема и для неё найдена запись TopicEmbed, эта запись удаляется, а значение её свойства embed_url переносится в старую запись TopicEmbed.
Настоятельно рекомендую сначала выполнить тестовый прогон (используя второй скрипт из этого сообщения), прежде чем запускать скрипт, который вносит реальные изменения. Если тестовый прогон выдаст какие-либо ошибки, вам нужно будет выяснить их причину. Просматривая код сейчас, я вижу возможную проблему: она может возникнуть, если на вашем сайте Discourse есть тема с заголовком, дублирующим заголовок встраиваемой темы, но у которой нет связанной записи TopicEmbed. Если это так, эту ситуацию можно будет исправить.