如何使用 Rails ActiveStorage 将一个对象从一个模型复制到另一个模型

ale*_*our 5 copy ruby-on-rails rails-activestorage

我目前正在使用 Rails 5.2.2。我正在尝试在 2 个模型之间复制一张图像。所以我想要 2 个文件,以及 blob 和附件中的 2 个条目。我的原始对象/图像在 AWS S3 上。

我的原始模型是照片,我的目标模型是图像

我试过这个:

image.file.attach(io: open(best_photo.full_url), filename: best_photo.filename, content_type: best_photo.content_type)
Run Code Online (Sandbox Code Playgroud)

full_url 是 photo.rb 中添加的一个方法:

include Rails.application.routes.url_helpers
def full_url
  rails_blob_path(self.file, disposition: "attachment", only_path: true)
end
Run Code Online (Sandbox Code Playgroud)

我收到此错误,就好像找不到文件一样:

没有这样的文件或目录@ rb_sysopen - /rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBHZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--2f865041b01d2f2c323a20879a855f25f231289d/881dc909-88ab-43b6-8148-5adbf888b399.jpg?disposition=attachment

我尝试了其他不同的方法(在使用 image_tag() 显示图像时使用此方法并正常工作:

def download_variant(version)
    variant = file_variant(version)
    return rails_representation_url(variant, only_path: true, disposition: "attachment")
  end
Run Code Online (Sandbox Code Playgroud)

同样的错误。

我验证了该文件存在于 S3 服务器上。我错过了什么 ?

谢谢。

Buc*_*000 6

更新为 Rails 6+ - 这对我有用

image.file.attach(io: StringIO.new(best_photo.download),
                  filename: best_photo.filename,
                  content_type: best_photo.content_type)
Run Code Online (Sandbox Code Playgroud)


mri*_*ula 5

您可以将源 blob 附加到目标:

image.file.attach best_photo.file.blob
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这不会创建**副本**,而只是引用原始 blob。如果您对其中一个对象有“dependent: :purge_later”,这可能会导致一些头痛...... (2认同)

ale*_*our 2

好,我知道了。我使用了service_url

image.file.attach(io: open(best_photo.file_variant("large").service_url), filename: best_photo.file.blob.filename, content_type: best_photo.file.blob.content_type)
Run Code Online (Sandbox Code Playgroud)