Rails - 为 S3 迁移重新保存所有模型

Posted

技术标签:

【中文标题】Rails - 为 S3 迁移重新保存所有模型【英文标题】:Rails - Resave All Models for S3 Migration 【发布时间】:2021-06-23 15:02:50 【问题描述】:

rails 6.1.3.2 aws-sdk-s3 gem

我目前有一个生产中的 Rails 应用程序,它使用 ActiveStorage 将图像数据附加到包装图像模型。它目前正在使用本地策略将图像保存到磁盘,我正在将其迁移到 S3。我没有使用回形针或类似的东西。

我成功设置了它。目前它被设置为主要使用本地并将 S3 作为镜像,以便我可以在迁移期间写入两个地方。但是文档说它只会在创建和更新记录时将新图像保存到 S3。我想“重新保存”生产中的所有模型以强制迁移发生。有人知道怎么做吗?

【问题讨论】:

【参考方案1】:

Looks like it was already answered!

如果您碰巧像我一样只能访问 Rails 控制台,那么此解决方案非常有效。如果您将此代码复制粘贴到控制台中,它将开始生成 S3 上传的输出。在其中 5k 之后,我完成了。非常感谢 Tayden 的解决方案。

all_services = [ActiveStorage::Blob.service.primary, *ActiveStorage::Blob.service.mirrors]

    # Iterate through each blob
    ActiveStorage::Blob.all.each do |blob|

      # Select services where file exists
      services = all_services.select  |file| file.exist? blob.key 

      # Skip blob if file doesn't exist anywhere
      next unless services.present?

      # Select services where file doesn't exist
      mirrors = all_services - services

      # Open the local file (if one exists)
      local_file = File.open(services.find |service| service.is_a? ActiveStorage::Service::DiskService .path_for blob.key) if services.select |service| service.is_a? ActiveStorage::Service::DiskService .any?

      # Upload local file to mirrors (if one exists)
      mirrors.each do |mirror|
        mirror.upload blob.key, local_file, checksum: blob.checksum
      end if local_file.present?

      # If no local file exists then download a remote file and upload it to the mirrors (thanks @Rystraum)
      services.first.open blob.key, checksum: blob.checksum do |temp_file|
        mirrors.each do |mirror|
          mirror.upload blob.key, temp_file, checksum: blob.checksum
        end
      end unless local_file.present?

【讨论】:

以上是关于Rails - 为 S3 迁移重新保存所有模型的主要内容,如果未能解决你的问题,请参考以下文章

从 ActiveStorage 迁移到 Shrine 的 Rake 任务

删除 Rails 应用程序并将其重新部署到 heroku

命名空间模型中的 Rails 关联

Rails 没有在开发模式下重新加载我的模型

为啥在保存对象后使用“重新加载”方法? (Hartl Rails Tut 6.30)

Ruby/Rails:重新打开与覆盖类