# 更新后出现离奇的加一错误

**URL:** https://meta.discourse.org/t/bizarre-off-by-one-post-update-error/203669
**Category:** Development
**Created:** [2021年九月15日 19:14 UTC](https://meta.discourse.org/t/bizarre-off-by-one-post-update-error/203669 "2021-09-15T19:14:07Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [2021年九月15日 19:14 UTC](https://meta.discourse.org/t/bizarre-off-by-one-post-update-error/203669/1 "2021-09-15T19:14:08Z")

</div>

我试图在 Rails 脚本中更新一组帖子。似乎存在某种奇怪的“差一错误”行为，导致某个帖子被更新为前一个帖子的值。

~~我将所有这些更新都改为直接执行 `post.raw.gsub()`，以“解决”内层循环中帖子（之前从主题帖子获取值）的问题，但现在主题 N 的主题帖子被更新为主题 N-1 中最后一个帖子的原始内容。~~

~~我现在更加困惑了，因为第一个（即主题）帖子通过 `tpost.raw.gsub!` 被更新为上一次迭代中 `post.raw.gsub!(preg,"#{$2}")` 的值。~~

编辑：好吧，我始终没弄清楚上一个版本哪里出了问题，但这里是一个会创建修订版的“更新部分帖子”脚本版本：

```ruby
def fix_slack_posts
  opts = { bypass_rate_limiter: true, bypass_bump: true, skip_validations: true }
  reg=/(\\*\\*)(This topic was automatically generated from Slack. You can find the original thread \\[here\\].+?\\))(\\*\\*\\.)?\\s*?([a-zA-Z, ()]* : )(.*)/m
  preg = /([a-zA-Z, ()]+? : )(.*)/m
  topic_posts = Post.where("raw like '**This topic was automatically%'")
  #topic_posts = Post.where(topic_id: [23934, 23935], post_number: 1)
  topic_posts.each do |tpost|
    begin
      puts "Fixing topic post #{tpost.id} with #{tpost.raw[0..30]}"
      puts tpost.raw.gsub(reg,"1 #{$1}\n2 #{$2}\n3 #{$3}\n4 #{$4}\n 5 #{$5}")
      raw = tpost.raw.gsub(reg,"#{$5}\n\n#{$2}.")
      puts "Fixing topic post #{tpost.id} with #{tpost.raw[0..30]}\n---\u003e#{raw}"
      user = User.find(tpost.user_id)
      if raw.length \u003e 10
        tpost.revise(user,{raw: raw,edit_reason: 'fix slack link location'}, opts)
      end
    rescue
      puts "Can't update topic post #{tpost.raw}"
    end
    posts = Post.where(topic_id: tpost.topic_id).where("post_number \u003e 1")
    posts.each do |post|
      if post.raw.gsub(preg,"#{$2}").length\u003e=10
        begin
          puts "Fixing post #{post.id} with #{post.raw[0..30]}"
          raw = post.raw.gsub(preg,"#{$2}")
          user = User.find(post.user_id)
          post.revise(user,{raw: raw,edit_reason: 'remove user name from text'}, opts)
        rescue
          puts "#{post.id}--cannot save #{post.raw}. "
        end
      end
    end
  end
end

```
