有什么想法如何使用 Refile 将正在运行的项目迁移到新Rails的 Active Storage ?
任何人都知道有关如何执行此操作的教程/指南吗?
谢谢, 帕特里克
答案 0 :(得分:1)
我在这里写了一篇关于它的简短文章,详细解释了这个过程: https://dev.to/mtrolle/migrating-from-refile-to-activestorage-2dfp
过去我将我的 Refile 附加文件托管在 AWS S3 中,所以我所做的是重构我的所有代码以使用 ActiveStorage。这主要涉及更新我的模型和视图以使用 ActiveStorage 语法。
然后我删除了 Refile gem 并将其替换为 ActiveStorage 所需的 gem,例如 image_processing
gem 和 aws-sdk-s3
gem。
最后我创建了一个 Rails DB 迁移文件来处理现有文件的实际迁移。在这里,我使用 Refile 附件遍历模型中的所有记录,以在 AWS S3 中找到它们各自的文件,下载它,然后使用 ActiveStorage 附件再次将其附加到模型。
移动文件后,我可以删除旧的 Refile 数据库字段:
require 'mini_magick' # included by the image_processing gem
require 'aws-sdk-s3' # included by the aws-sdk-s3 gem
class User < ActiveRecord::Base
has_one_attached :avatar
end
class MovingFromRefileToActiveStorage < ActiveRecord::Migration[6.0]
def up
puts 'Connecting to AWS S3'
s3_client = Aws::S3::Client.new(
access_key_id: ENV['AWS_S3_ACCESS_KEY'],
secret_access_key: ENV['AWS_S3_SECRET'],
region: ENV['AWS_S3_REGION']
)
puts 'Migrating user avatar images from Refile to ActiveStorage'
User.where.not(avatar_id: nil).find_each do |user|
tmp_file = Tempfile.new
# Read S3 object to our tmp_file
s3_client.get_object(
response_target: tmp_file.path,
bucket: ENV['AWS_S3_BUCKET'],
key: "store/#{user.avatar_id}"
)
# Find content_type of S3 file using ImageMagick
# If you've been smart enough to save :avatar_content_type with Refile, you can use this value instead
content_type = MiniMagick::Image.new(tmp_file.path).mime_type
# Attach tmp file to our User as an ActiveStorage attachment
user.avatar.attach(
io: tmp_file,
filename: "avatar.#{content_type.split('/').last}",
content_type: content_type
)
if user.avatar.attached?
user.save # Save our changes to the user
puts "- migrated #{user.try(:name)}'s avatar image."
else
puts "- \e[31mFailed to migrate the avatar image for user ##{user.id} with Refile id #{user.avatar_id}\e[0m"
end
tmp_file.close
end
# Now remove the actual Refile column
remove_column :users, :avatar_id, :string
# If you've created other Refile fields like *_content_type, you can safely remove those as well
# remove_column :users, :avatar_content_type, :string
end
def down
raise ActiveRecord::IrreversibleMigration
end
end