ActiveStorage可以创建用于直接上传的Blob,然后在上传完成之前将其附加到模型吗?

时间:2019-07-16 12:21:46

标签: ruby-on-rails amazon-s3 rails-activerecord rails-activestorage

我正在创建一个包含文件上传服务的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中。这样做是有道理的,但是似乎没有一种跳过检查的方法。

1 个答案:

答案 0 :(得分:0)

我认为,在上传Blob之前附加附件的原因实际上并没有我想像的那样深思熟虑。我不再试图绕过S3检查,但是在调查它时确实找到了解决原始问题的方法。

ValueTransformerActiveStorage::Blob实际上都是ActiveStorage::Attachment的子类。这意味着您基本上可以将它们视为普通模型。 ActiveRecord::Base被设置为多态关联,以在ActiveStorage::Attachment与任何其他记录之间创建多对多关系。您所需要做的就是使用正确的参数调用ActiveStorage::Blob,以建立新创建的Blob与记录之间的关系。

问题中的代码将被重写为:

ActiveStorage::Attachment.create