将 ActiveStorage 附件附加到现有 S3 文件



我正在构建一个PDF解析器,它触发了一个Sidekiq工作人员,以OCR解析存储在S3中的文档中的数据。解析后,数据存储在文档模型中。

如何将现有的 S3 存储桶文件附加到 ActiveStorage 中的Document.attachment.attach,而无需在 S3 中复制该文件(通过 File.open 等(?

这可以通过在创建 blob 后对其进行轻微操作来完成。

存储.yml

amazon:
service: S3
access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %>
secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
region: <%= ENV['AWS_REGION'] %>
bucket: <%= ENV['S3_BUCKET'] %>

app/models/document.rb

class Document < ApplicationRecord
has_one_attached :pdf
end

导轨控制台

key = "<S3 Key of the existing file in the same bucket that storage.yml uses>"
# Create an active storage blob that will represent the file on S3
params = { 
filename: "myfile.jpg", 
content_type:"image/jpeg", 
byte_size:1234, 
checksum:"<Base 64 encoding of the MD5 hash of the file's contents>" 
}
blob = ActiveStorage::Blob.create_before_direct_upload!(params)
# By default, the blob's key (S3 key, in this case) a secure (random) token
# However, since the file is already on S3, we need to change the 
# key to match our file on S3
blob.update_attribute(:key,key)
# Now we can create a document object connected to your S3 file
d = Document.create! pdf:blob.signed_id
# in your view, you can now use
url_for d.pdf

此时,您可以像使用任何其他活动存储附件一样使用Document对象的pdf属性。

特洛伊的回答对我来说很好用!我还发现从对象的 s3 实例中提取有关对象的元数据很有帮助。像这样:

s3 = Aws::S3::Resource.new(region: "us-west-1")
obj = s3.bucket("my-bucket").object("myfile.jpg")    
params = {
filename: obj.key, 
content_type: obj.content_type, 
byte_size: obj.size, 
checksum: obj.etag.gsub('"',"")
}

我只有 46 分,所以我把它作为答案而不是评论:/

最新更新