Re-adding missing uploads to the database

OK、Claudeとたくさんの賞賛で解決しました。同様または同じ問題を持つ他の誰かを助けるために、私が行ったことを共有します。

これが最も賢明で最適な方法であるかどうかはわかりませんが、私にとっては機能した方法です。

私は専門家ではなく、常に学んでいる初心者であることを念頭に置いて、注意してください。

問題点(S3 → ローカルファイルシステム)

AWS S3からローカルFSに移行した後、多くの画像がtransparent.pngとして表示されました。ファイルは常にディスク上にありましたが、Discourseはそれらを解決できませんでした。

根本原因は壊れた連鎖でした。

  1. upload://の短いURL(base62でエンコードされたSHA1)を持つ投稿
  2. SHA1 → ローカルファイルパスへのデータベースuploadsマッピング。
  3. SHA1ハッシュで名前が付けられたファイルを保存するファイルシステム

移行によりファイルは正しくディスクに移動しましたが、uploads DBレコードは存在しませんでした。一致するレコードがないため、Discourseはtransparent.pngにフォールバックします。

解決策(レコードの作成とリベイク)

孤立したファイルから失われたアップロードレコードの作成:

dir = Rails.root.join("public", "uploads", "default", "original")
created = 0

Dir.glob(dir.join("**", "*")).select { |f| File.file?(f) }.each do |path|
  sha = File.basename(path, File.extname(path))
  next if Upload.find_by(sha1: sha)

  ext = File.extname(path).delete(".")
  relative = path.sub("#{Rails.root}/public", "")

  u = Upload.new
  u.sha1 = sha
  u.url = relative
  u.original_filename = File.basename(path)
  u.filesize = File.size(path)
  u.extension = ext
  u.user_id = -1
  u.save!(validate: false)

  created += 1
  puts "Created upload #{u.id}: #{sha}"
end

puts "Total created: #{created}"

復元されたアップロードを参照する投稿のリベイク:

fixed_posts = 0

Upload.where(user_id: -1).find_each do |u|
  short = u.short_url
  next unless short

  Post.where("raw LIKE '%upload://%'").find_each do |p|
    urls = p.raw.scan(/upload:\/\/^[^\s\]\)]+/)
    urls.each do |url|
      decoded = Upload.sha1_from_short_url(url)
      if decoded == u.sha1
        p.rebake!
        fixed_posts += 1
        puts "Rebaked post #{p.id}"
        break
      end
    end
  end
end

puts "Total rebaked: #{fixed_posts}"

失われた最適化の再生成:

元のファイルを修正した後、最適化されたファイル(1X、2Xなど)を移入する必要があります。

rake uploads:regenerate_missing_optimized

安全なロールバック(念のため)

作成されたすべてのレコードは user_id: -1 を使用します。元に戻すには:

Upload.where(user_id: -1).delete_all

delete_allはコールバックをスキップするため、ファイルシステム上のファイルは変更されません。

以前は誤ってdestroy_allを使用したため、コールバックがトリガーされ、ファイルが墓石(tombstone)に移動されました。

テストに使用した個別のものを回復し、アプローチを再構築しました。

「いいね!」 3