我正在尝试从Paperclip迁移到Active Storage,但是在运行迁移时却不断收到未定义方法`request_uri'的错误。这就是我的ConvertToActiveStorage迁移的样子(注意:我首先在开发环境中测试此迁移,该开发环境已连接到我的AWS S3开发存储桶-因此我的文件不在本地)
我猜想这可能与我的S3 URL有关,后者的格式为“ //s3.amazonaws.com / .......”,这与我以“ //”而不是“ https”开头?如果可以,我该如何避免呢?
Dir[Rails.root.join("app/models/**/*.rb")].sort.each { |file| require file }
class ConvertToActiveStorage < ActiveRecord::Migration[5.2]
require 'open-uri'
def up
# postgres
get_blob_id = 'LASTVAL()'
# mariadb
# get_blob_id = 'LAST_INSERT_ID()'
# sqlite
# get_blob_id = 'LAST_INSERT_ROWID()'
active_storage_blob_statement =
ActiveRecord::Base.connection.raw_connection.prepare('
active_storage_blob_statement', <<-SQL)
INSERT INTO active_storage_blobs (
key, filename, content_type, metadata, byte_size, checksum, created_at
) VALUES ($1, $2, $3, '{}', $4, $5, $6)
SQL
active_storage_attachment_statement = ActiveRecord::Base.connection.raw_connection.prepare('active_storage_attachment_statement', <<-SQL)
INSERT INTO active_storage_attachments (
name, record_type, record_id, blob_id, created_at
) VALUES ($1, $2, $3, #{get_blob_id}, $4)
SQL
models = ActiveRecord::Base.descendants.reject(&:abstract_class?)
transaction do
models.each do |model|
attachments = model.column_names.map do |c|
if c =~ /(.+)_file_name$/
$1
end
end.compact
model.find_each.each do |instance|
attachments.each do |attachment|
if instance.send(attachment).exists?
active_storage_blob_statement.execute(
key(instance, attachment),
instance.send("#{attachment}_file_name"),
instance.send("#{attachment}_content_type"),
instance.send("#{attachment}_file_size"),
checksum(instance.send(attachment)),
instance.updated_at.iso8601
)
active_storage_attachment_statement.
execute(attachment, model.name, instance.id, instance.updated_at.iso8601)
end
end
end
end
end
active_storage_attachment_statement.close
active_storage_blob_statement.close
end
def down
raise ActiveRecord::IrreversibleMigration
end
private
def key(instance, attachment)
# SecureRandom.uuid
# Alternatively:
instance.send("#{attachment}_file_name")
end
def checksum(attachment)
# local files stored on disk:
# url = attachment.path
# Digest::MD5.base64digest(File.read(url))
# remote files stored on another person's computer:
url = attachment.url
Digest::MD5.base64digest(Net::HTTP.get(URI(url)))
end
end