댓글에 Discourse 통합을 사용하는 사이트 이전

안녕하세요,

저는 서브도메인에 위치한 블로그의 댓글을 호스팅하기 위해 Discourse 통합 기능을 사용하고 있습니다. 하지만 이제 블로그를 최상위 도메인의 서브 URL로 옮기려고 합니다.

예를 들어, 현재 블로그는

blog.somedomain.com

에 위치해 있지만, 앞으로는

somedomain.com/blog

으로 옮기려 합니다.

기존의 Discourse 댓글 주제가 새 블로그 위치를 가리키도록 어떻게 업데이트해야 할까요?

게시물 내용을 수동으로 업데이트할 수는 있겠지만, URL이 달라졌기 때문에 새 블로그 사이트를 방문하면 새 주제가 생성되는 건 아닌지 걱정됩니다.

(참고로 해당 블로그는 Ghost 블로그입니다. 이 정보가 도움이 될 수 있을지 모르겠습니다.)

도움 주시면 감사하겠습니다.
Brad

최근 이와 유사한 문제를 처리한 적이 있습니다. 당시 해당 사이트는 블로그의 도메인을 변경해버렸고, 그 결과 이미 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 사이트에 있는 경우 발생할 수 있는 문제가 있습니다. 그런 경우라면 처리할 수 있는 사항입니다.

Simon, 안녕하세요.

정말 유용한 정보네요. 감사합니다.

제 경우에는 블로그 사이트가 아직 이전되지 않았고 중복된 항목도 없어서 상황이 더 간단한 것 같습니다. 기존 임베드 항목의 URL을 새 URL로만 업데이트하면 될 것 같아요.

저는 이전에 Ruby를 사용해 본 적이 없지만, Simon님의 예시를 참고하여 아래 스크립트를 직접 작성해 보았습니다. 토픽 임베드 업데이트 외에도 관련 게시물의 텍스트와 링크도 함께 업데이트하도록 확장했습니다.

방향성이 맞는지 간단히 검토해 주시겠어요? 업데이트 부분을 주석 처리한 채로 실행해 보니 올바르게 표시되는 것 같습니다.

(참고로: 이런 스크립트는 보통 어떻게 실행하나요? 저는 텍스트 편집기로 편집한 후 콘솔에 붙여넣는 방식으로 작업하고 있습니다)

Brad

original_embeds = TopicEmbed.where("embed_url LIKE ?", "https://blog.cantabilesoftware.com%")

old_url_prefix = "https://blog.cantabilesoftware.com/"
new_url_prefix = "https://www.cantabilesoftware.com/blog/"
original_embeds.each do |original_embed|

    new_embed_url = original_embed.embed_url
    new_embed_url.sub!(old_url_prefix, new_url_prefix)
    puts "Updating TopicEmbed: #{original_embed.id} with new url: #{new_embed_url}"
    #original_embed.update(embed_url: new_embed_url)

    post = Post.find_by(id: original_embed.post_id)
    new_raw = post.raw
    new_raw.gsub!(old_url_prefix, new_url_prefix)
    new_cooked = post.cooked
    new_cooked.gsub!(old_url_prefix, new_url_prefix)

    puts "Updating raw with #{new_raw}"
    puts "Updating cooked with #{new_cooked}"

    #post.update(raw: new_raw, cooked: new_cooked)
    
end

기록으로 남기자면, 위 방법은 정상적으로 작동했습니다. 제가 따랐던 전체 과정은 다음과 같습니다:

  1. Discourse를 읽기 전용으로 설정
  2. 백업 생성
  3. 위 스크립트 실행
  4. Discourse 페이지가 올바르게 업데이트되었는지 확인
  5. 기존 블로그를 종료하고 새 블로그를 시작
  6. 기존 블로그 사이트에서 새 사이트로 리다이렉트 설정
  7. Discourse 읽기 전용 모드 해제
  8. Discourse 임베딩 설정을 변경하여 기존 도메인은 허용하지 않고 새 도메인은 허용하도록 변경
  9. 새 블로그에 임베딩 설정

이 문제에 대해 도움을 주신 @simon님께 감사드립니다. :+1: