Discourseインテグレーションを使用したサイトのコメントの移行

こんにちは皆さん、

私はブログのコメントをホストするために Discourse の統合を使用していますが、ブログをサブドメインからトップレベルドメインのサブディレクトリへ移動させたいと考えています。

例:現在、ブログは以下の場所にあります。

blog.somedomain.com

これを以下の場所へ移動させたいです。

somedomain.com/blog

既存の Discourse のコメントトピックを新しいブログの場所へどのように更新すればよいでしょうか?

投稿の内容を手動で更新することはできると考えられますが、新しいブログサイトへアクセスした際に、URL が異なるため新しいトピックが作成されてしまうのでしょうか?

(参考までに、このブログは Ghost ブログです)

ご助言をいただければ幸いです。
Brad

「いいね!」 1

私は最近、これと類似の事案に対応しました。そのケースでは、サイト側がすでにブログのドメインを変更してしまっていました。その結果、すでに Discourse トピックが生成されていたブログ記事に対して、重複するトピックが Discourse 上に作成されてしまいました。

解決策としては、サイトの Rails コンソールからスクリプトを実行し、旧ドメインの embed_url を持つすべての TopicEmbed エントリを検出するというものでした。その後、重複トピックに対応する TopicEmbed エントリを削除し、embed_url の値を正しいドメインに更新しました。さらに、新たに生成されたトピックも削除しました。

この問題の解決方法は少し面倒に思えます。私が使用したスクリプトの詳細を共有することもできますが、この問題へのアプローチについて他の人のアイデアを聞ければ素晴らしいと思います。埋め込みトピックに関しては、今後もしばしばこの種の課題が発生するはずです。

「いいね!」 1

こんにちは、サイモンさん。

ありがとうございます。

それは素晴らしいですね(そして、その実行方法に関する情報も助かります)。

元の投稿へのリンクが含まれている投稿内容を手動で更新する必要があると思います(つまり、「これは…の元の投稿に関する補足ディスカッショントピックです」といった部分)。

同意します。めったに行う必要はありませんが、行うとなると非常に面倒ですね。

ブラッド

スクリプトをここに共有します。これが問題に対する最善のアプローチであるとは限りませんので、ご了承ください。このスクリプトは、ドメイン名の変更により重複トピックの作成が始まったに実行する必要があります。トピックは、ユーザーが新しいドメイン名のブログ記事にアクセスし始めてから作成されるため、すべてのトピックを捕捉するにはスクリプトを複数回実行する必要があるかもしれません。スクリプトの1行目にある 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 コンソールに入り、スクリプトの1行目をコンソールにコピーして実行してください。これにより、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 "(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 レコードに引き継がれます。

実際の変更を行うスクリプトを実行する前に、必ずダミー実行(この投稿の2番目のスクリプトを使用)を行ってください。ダミー実行でエラーが返された場合は、その原因を確認する必要があります。現在コードを見ると、Discourse サイトに埋め込まれたトピックと重複するタイトルを持つトピックが存在し、かつそれに TopicEmbed が関連付けられていない場合に発生しうる問題が考えられます。その場合は、何らかの対処が必要になる可能性があります。

「いいね!」 3

こんにちは、Simonさん。

とても参考になりました。ありがとうございます。

私の場合は、ブログサイトはまだ移動されておらず重複もないため、さらにシンプルだと思います。必要なのは、既存の埋め込みエントリを新しい URL に更新することだけでしょう。

Ruby は使ったことがありませんが、あなたの例を参考に下のスクリプトを無理やり組み立てました。トピックの埋め込みを更新するだけでなく、関連する投稿内のテキストやリンクも更新するように拡張しました。

方向性が合っているか、一度軽く見ていただけますか?更新部分をコメントアウトして実行しましたが、正しい内容が表示されているようです。

(余談ですが、これらのスクリプトを実行する通常の方法は何ですか?私はテキストエディタで編集してから、コンソールに貼り付けて実行していました)

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
「いいね!」 2

念のため、上記の手順は正常に動作しました。私が行った完全な手順は以下の通りです:

  1. Discourse を読み取り専用モードに設定
  2. バックアップを作成
  3. 上記のスクリプトを実行
  4. Discourse のページが正しく更新されたか確認
  5. 旧ブログをシャットダウンし、新ブログを起動
  6. 旧ブログサイトから新ブログへのリダイレクトを設定
  7. Discourse の読み取り専用モードを解除
  8. Discourse の埋め込み設定を再構成し、旧ドメインを拒否して新ドメインを許可するように変更
  9. 新ブログで埋め込みを設定

この件でご支援いただいた @simon さんに心から感謝します。:+1:

「いいね!」 1