최근 이와 유사한 문제를 처리한 적이 있습니다. 당시 해당 사이트는 블로그의 도메인을 변경해버렸고, 그 결과 이미 Discourse에서 토픽이 생성된 블로그 게시물에 대해 중복된 토픽들이 Discourse에 생성되었습니다.
해결 방법은 사이트의 Rails 콘솔에서 스크립트를 실행하여 구 도메인의 embed_url을 가진 모든 TopicEmbed 항목을 찾는 것이었습니다. 이후 중복된 토픽에 대한 TopicEmbed 항목을 삭제한 후, 해당 embed_url 값들을 올바른 도메인으로 업데이트했습니다. 그리고 새로 생성된 토픽들을 삭제했습니다.
이 문제는 해결하기가 다소 복잡해 보입니다. 제가 사용한 스크립트에 대한 세부 정보를 게시할 수 있지만, 이 문제를 접근하는 방법에 대해 다른 분들이 아이디어를 갖고 있다면 의견을 들어보고 싶습니다. 임베디드 토픽을 사용할 때 이런 문제는 주기적으로 발생하게 마련이니까요.
스크립트를 여기에 공유하겠습니다. 이 문제가 최선의 접근 방식인지 확신은 없습니다. 이 스크립트는 도메인 이름 변경으로 인해 중복 토픽 생성이 시작된 _이후_에 실행되어야 합니다. 사용자가 새 도메인 이름으로 블로그 게시물에 방문하기 시작할 때까지 토픽이 생성되지 않으므로, 모든 토픽을 포착하려면 스크립트를 여러 번 실행해야 할 가능성이 큽니다. 스크립트 첫 번째 줄의 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 "Destroying TopicEmbed: #{new_embed.id} Topic: #{new_embed.topic_id}"
new_embed.destroy
puts "Updating TopicEmbed: #{original_embed.id} New embed_url: #{new_embed_url}"
original_embed.update(embed_url: new_embed_url)
end
end
end
스크립트를 실행하려면 사이트의 Rails 콘솔에 접속한 후, 스크립트의 첫 번째 줄을 콘솔에 복사하여 실행합니다. 그러면 original_embeds 변수에 TopicEmbed 레코드 배열이 설정됩니다. 이 작업이 완료되면 스크립트의 나머지 부분을 콘솔에 복사하여 실행할 수 있습니다.
안전을 위해 스크립트를 실행하기 전에 사이트 데이터베이스의 백업을 만드는 것이 좋습니다. 또한 변경 사항이 발생하지 않는 스크립트의 드라이 런(dry run)을 수행하는 것도 좋은 아이디어입니다. 이를 위해 다음 코드를 사용할 수 있습니다:
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 "(Dry run) Destroying TopicEmbed: #{new_embed.id} Topic: #{new_embed.topic_id}"
#new_embed.destroy
puts "(Dry run) Updating TopicEmbed: #{original_embed.id} New embed_url: #{new_embed_url}"
#original_embed.update(embed_url: new_embed_url)
end
end
end
데이터베이스에 실제 변경 사항을 적용하는 줄을 주석 해제하기 전에 출력이 합리적인지 확인하세요.
스크립트가 수행하는 작업:
original_embeds 변수에는 블로그의 이전 도메인과 일치하는 모든 TopicEmbed 레코드가 설정됩니다.
각 original_embeds에 대해 중복된 제목을 가진 토픽(새로운 중복 임베드)을 찾으려 시도합니다.
중복 토픽이 발견되고 해당 중복 토픽에 TopicEmbed 레코드가 발견되면, 해당 TopicEmbed 레코드가 삭제되고 그 embed_url 속성의 값이 기존 TopicEmbed 레코드로 이전됩니다.
실제 변경 사항을 적용하는 스크립트를 실행하기 전에 드라이 런(이 게시물의 두 번째 스크립트 사용)을 수행하는 것을 권장합니다. 드라이 런에서 오류가 반환되면 원인을 파악해야 합니다. 현재 코드를 살펴보면, 내장된 토픽과 제목이 중복되었지만 TopicEmbed가 연결되지 않은 토픽이 Discourse 사이트에 있는 경우 발생할 수 있는 문제가 있습니다. 그런 경우라면 처리할 수 있는 사항입니다.