# 移动使用 Discourse 集成进行评论的网站

**URL:** https://meta.discourse.org/t/moving-a-site-that-uses-discourse-integrations-for-comments/172688
**Category:** Support
**Created:** [2020年十二月8日 23:23 UTC](https://meta.discourse.org/t/moving-a-site-that-uses-discourse-integrations-for-comments/172688 "2020-12-08T23:23:50Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![brobinson](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/brobinson/32/119705_2.png) [@brobinson](https://meta.discourse.org/u/brobinson)
#### Post date: [2020年十二月8日 23:23 UTC](https://meta.discourse.org/t/moving-a-site-that-uses-discourse-integrations-for-comments/172688/1 "2020-12-08T23:23:50Z")

</div>

大家好，

我正在使用 Discourse 集成来托管位于子域名的博客评论，但现在希望将博客迁移到顶级域名的子路径下。

例如：目前博客位于

> [blog.somedomain.com](http://blog.somedomain.com)

但我希望将其迁移到

> [somedomain.com/blog](http://somedomain.com/blog)

我该如何更新现有的 Discourse 评论主题，使其指向新的博客位置？

我猜可以手动更新帖子内容，但访问新的博客站点时，由于 URL 已更改，是否会创建新的主题？

（该博客是 Ghost 博客，如有影响请告知）

任何帮助都将不胜感激。  
Brad

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [2020年十二月9日 20:36 UTC](https://meta.discourse.org/t/moving-a-site-that-uses-discourse-integrations-for-comments/172688/2 "2020-12-09T20:36:53Z")

</div>

> [@brobinson](#):
>
> 我目前使用 Discourse 集成来托管位于子域名的博客评论，但希望将博客迁移到顶级域名的子路径下。

我最近处理过类似的情况。当时，该网站已经更改了博客的域名。这样做导致的结果是，对于任何已经生成 Discourse 主题的博客文章，Discourse 上都会创建重复的主题。

解决方案是从网站的 Rails 控制台运行一个脚本，查找所有 `embed_url` 指向旧域名的 `TopicEmbed` 条目。在删除重复主题对应的 `TopicEmbed` 条目后，将这些 `embed_url` 值更新为正确的域名。随后，删除新生成的重复主题。

这似乎是一种解决该问题的复杂方法。我可以发布我所用脚本的详细信息，但也非常希望听到其他人是否有更好的处理思路。随着嵌入主题的普及，这类问题迟早会再次出现。

---

<div class="post-metadata">

### Author: ![brobinson](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/brobinson/32/119705_2.png) [@brobinson](https://meta.discourse.org/u/brobinson)
#### Post date: [2020年十二月10日 00:21 UTC](https://meta.discourse.org/t/moving-a-site-that-uses-discourse-integrations-for-comments/172688/4 "2020-12-10T00:21:28Z")

</div>

嗨，Simon，

谢谢。

> [@simon](#):
>
> 我可以发布我所用脚本的详细信息

那太棒了（任何关于如何运行该脚本的信息都会有帮助）。

我想我需要手动更新那些链接回原始文章的帖子内容。（例如，帖子文本中写着“这是原始条目……的配套讨论主题”的部分。）

> [@simon](#):
>
> 这似乎是解决该问题的一种困难方式。……嵌入主题时，这种情况迟早会时不时出现

我同意——虽然这种情况很少需要处理，但一旦需要，似乎非常棘手。

Brad

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [2020年十二月10日 01:27 UTC](https://meta.discourse.org/t/moving-a-site-that-uses-discourse-integrations-for-comments/172688/5 "2020-12-10T01:27:54Z")

</div>

我将在此分享脚本。请注意，我不确定这是否是解决该问题的最佳方案。该脚本需要在域名更改导致重复主题开始创建 **之后** 运行。由于直到用户开始访问新域名下的博客文章时才会创建这些主题，因此您可能需要多次运行该脚本以捕获所有主题。请务必将脚本第一行中的 `old.domain.com` 替换为您博客原来的实际域名。

```ruby
# 首先运行此部分：
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` 记录的数组。完成后，您可以将脚本的其余部分复制到控制台中并运行。

为了安全起见，在运行脚本之前，您应该备份网站的数据库。此外，最好先进行一次不执行任何更改的试运行。以下代码可实现此目的：

```ruby
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` 记录，则该 `TopicEmbed` 记录将被删除，其 `embed_url` 属性的值将被转移到旧的 `TopicEmbed` 记录中。

我强烈建议在执行实际更改的脚本之前先进行试运行（使用本文中的第二个脚本）。如果试运行返回任何错误，您需要查明原因。查看代码后，我发现了一个潜在问题：如果您的 Discourse 网站上存在一个主题，其标题与某个嵌入主题的标题重复，但该主题没有关联的 `TopicEmbed`，则可能会发生这种情况。如果是这种情况，是可以处理的。

---

<div class="post-metadata">

### Author: ![brobinson](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/brobinson/32/119705_2.png) [@brobinson](https://meta.discourse.org/u/brobinson)
#### Post date: [2020年十二月10日 03:02 UTC](https://meta.discourse.org/t/moving-a-site-that-uses-discourse-integrations-for-comments/172688/6 "2020-12-10T03:02:39Z")

</div>

嗨，Simon，

这真的很有帮助，谢谢。

就我的情况而言，我觉得事情更简单，因为博客站点尚未迁移，而且我没有任何重复内容。我想我只需要更新现有的嵌入条目，使用新的 URL 即可。

我从未使用过 Ruby，但根据你的示例，我拼凑出了下面的脚本。除了更新主题嵌入外，我还扩展了它，以同时更新相关帖子中的文本和链接。

能否请你快速过目一下，确认我是否走在正确的轨道上？我已经在注释掉更新操作的情况下运行了它，看起来它显示的内容是正确的。

（顺便问一下：运行这些脚本的常规方式是什么？我一直在文本编辑器中编辑，然后粘贴到控制台中执行。）

Brad

```plaintext
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

```

---

<div class="post-metadata">

### Author: ![brobinson](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/brobinson/32/119705_2.png) [@brobinson](https://meta.discourse.org/u/brobinson)
#### Post date: [2020年十二月10日 05:29 UTC](https://meta.discourse.org/t/moving-a-site-that-uses-discourse-integrations-for-comments/172688/7 "2020-12-10T05:29:12Z")

</div>

为记录在案，上述操作运行顺利。以下是我遵循的完整流程：

1. 将 Discourse 设置为只读模式
2. 创建备份
3. 运行上述脚本
4. 确认 Discourse 页面已正确更新
5. 关闭旧博客并启动新博客
6. 设置从旧博客站点到新站点的重定向
7. 关闭 Discourse 的只读模式
8. 重新配置 Discourse 嵌入设置，禁止旧域名并允许新域名
9. 在新博客上设置嵌入功能

非常感谢 @simon 在此过程中提供的帮助。👍
