我正在创建一个包含文件上传服务的api,其中上传的文件可以具有用户输入的额外信息,并存储在Project模型中。当客户端请求从服务器直接上传时,我还想创建一个新项目,并在客户端上传到S3时附加blob。但是,如果S3中尚不存在Blob,则ActiveStorage似乎不允许附加该Blob。
我考虑了何时附加Blob的几种不同选择,但我认为在创建Blob和直接上载凭据时进行此操作是我需要的最佳选择。由于我需要ActiveStorage提供的默认控制器未涵盖的一些额外逻辑,因此我编写了自己的逻辑。在其中,我创建了一个直接上传的Blob,创建了一个项目,将该Blob附加到该项目,然后返回签名的上传URL,标题和项目ID。但是,当我尝试将Blob附加到项目时,它给我一个Aws::S3::Errors::NoSuchKey
错误。
在我的控制器中:
Project.transaction do
# Create a project with default attributes
project = create_draft_project(project_title)
# Create a blob before direct upload to generate a signed url
blob = ActiveStorage::Blob.create_before_direct_upload!(
filename: filename,
byte_size: byte_size,
checksum: checksum,
content_type: content_type
)
# Attach the blob to the project. This is where it errors.
project.file.attach(blob.signed_id)
end
# Render the success response
success_response(project, blob)
在我的项目模型中:
has_one_attached :file
我希望ActiveStorage可以让我附加blob,即使该blob尚未上传,但实际上它确实会在执行此操作之前检查文件是否在S3中。这样做是有道理的,但是似乎没有一种跳过检查的方法。
答案 0 :(得分:0)
我认为,在上传Blob之前附加附件的原因实际上并没有我想像的那样深思熟虑。我不再试图绕过S3检查,但是在调查它时确实找到了解决原始问题的方法。
ValueTransformer
和ActiveStorage::Blob
实际上都是ActiveStorage::Attachment
的子类。这意味着您基本上可以将它们视为普通模型。 ActiveRecord::Base
被设置为多态关联,以在ActiveStorage::Attachment
与任何其他记录之间创建多对多关系。您所需要做的就是使用正确的参数调用ActiveStorage::Blob
,以建立新创建的Blob与记录之间的关系。
问题中的代码将被重写为:
ActiveStorage::Attachment.create