本文介绍了Active Storage public_url 不返回 key/filename.extension的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

在此 PR 中将公共选项添加到 Active Storage:

现在,下面是存储在 AWS S3 上的上述文件的示例 URL:3996deee6

查看 url 如何包含秘密令牌和到期时间?建议不要有永久的文件 url.

附言将 AWS S3 连接到您的应用程序时,不要忘记添加

The public option is added to Active Storage in this PR: https://github.com/rails/rails/pull/36729
In it he clearly says: "In the public bucket, the directory structure is /[key]/[filename]"

Which makes sense and is exactly what I want. I want to be able (for example) to email the link to someone and allow them to download the file. So I need the filename.extension. But when I spin up a Rails 6.1 app the uploads to my bucket do not have the filename after them.The files do appear in my bucket, but only as their key. Not key/filename.

amazon:
  service: S3
  access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
  secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
  region: us-east-1
  bucket: mybucket
  public: true

The uploading works fine. The files are uploaded and appear in my bucket. But in the view <%= @user.avatar.url %> returns https://s3.amazonaws.com/mybucket/g3ci2umbfj6wkxyggx7arhekxfib I want it to return https://s3.amazonaws.com/mybucket/g3ci2umbfj6wkxyggx7arhekxfib/myfile.pngThis is really annoying me because in the PR the author clearly states that the public files are saved as key/filename.extension

So the question: In Rails 6.1 does the url method return the filename as part of the path or not. And if not why does the author say that it does? And if not is there a better way than patching key?

解决方案

TLDR:

= link_to @user.avatar.filename, rails_blob_path(@user.avatar, disposition: "course.avatar"), target: :_blank

will give you a download link like https://corsego-production.s3.eu-central-1.amazonaws.com/3gbpl68kckpkyrbjoslsl254th0u?response-content-disposition=inline&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEGgaCmV1LBuuKkri8zL3ohM4h9STzhTsnavAgulrcpBavL0POXg%3D%3D&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20201002T170820Z&X-Amz-SignedHeaders=host&X-Amz-Expires=300&X-Amz-Credential=ASIA5RINJ20201002%2Feu-central-1%2Fs3%2Faws4_request&X-Amz-Signature=0a205d713ebaa9d3ca9d62


@user.avatar.url is not supposed to return anything!

@user.avatar is supposed to return something like #<ActiveStorage::Attached::One:0x00007f15986ee4c0>

When creating an attachment with Active Storage, the following fields about the attachment are automatically populated and saved as active_storage_blobs:

  create_table "active_storage_blobs", force: :cascade do |t|
    t.string "key", null: false
    t.string "filename", null: false
    t.string "content_type"
    t.text "metadata"
    t.bigint "byte_size", null: false
    t.string "checksum", null: false
    t.datetime "created_at", null: false
    t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true
  end

Let's say you upload an image with active storage. The above Table will be populated in a following way:

Id: 1
Key: sy2y1ytw7zob6mwtnwc1552cdp5l
Filename: Screenshot 2020-10-02 125405.png
Content_type: image/png
Metadata: {"identified"=>true, "analyzed"=>true}
Byte_size: 1550
Checksum: mGPerbRMj6LXbPKhqKd4bA

To display the user avatar as an image, you must call = image_tag @user.avatar

= rails_blob_url(@user.avatar) will give you something like https://example.com/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBCZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--5fb10a9c8e9f2c4e7099eee21c1dc2ff0343c210/Screenshot%202020-10-02%20125405.png

= @user.avatar will give you something like #<ActiveStorage::Attached::One:0x00007f1589293dd0>

= url_for(@user.avatar) will give you something like /rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBCZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--5fb10a9c8e9f2c4e7099eee21c1dc2ff0343c210/Screenshot%202020-10-02%20125405.png

The second table in the migrations created by active_storage is this:

  create_table "active_storage_attachments", force: :cascade do |t|
    t.string "name", null: false
    t.string "record_type", null: false
    t.bigint "record_id", null: false
    t.bigint "blob_id", null: false
    t.datetime "created_at", null: false
    t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id"
    t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true
  end

basically it connects the blob with a specific record in your application (basically the avatar is a blob, the @user is the record, and they are associated via the active_storage_attachments table.

So you can also run the following commands on the @user.avatar method:

@user.avatar.name #Avatar
@user.avatar.record_type #User
@user.avatar.record_id #2 (user id)
@user.avatar.blob_id #1 (blob id)

Now, below is an example url to the above file stored on AWS S3:https://corsego-production.s3.eu-central-1.amazonaws.com/3gbpl68kckpkyrbjoslsl254th0u?response-content-disposition=inline&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEGgaCmRzBFAiBSJ2QIEqs1opj%2BuCR74CDMt67ueDTTQIhAOJGGy2wfmxmGUwpQe9cyc84ZhUhuWKHdVgTUctbtGrVKdinkpg0w7OikcyNYpnbq%2FefcTmEgRvIlPO%2B0itFxUr8mKUvnDYSuKkri8zL3ohM4h9STzhTsnavAgulrcpBavL0POXg%3D%3D&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20201002T170820Z&X-Amz-SignedHeaders=host&X-Amz-Expires=300&X-Amz-Credential=ASIA5RINJLY2F20201002%2Feu-central-2%2Fs3%2Faws4_request&X-Amz-Signature=0a205d713ebaaa339ad4ee09db9dfe16986e69d3ca9d62

See how the url contains a secret token and an expiry time? It is advised not to have permanent urls to files.

P.S. When connecting AWS S3 to your application, don't forget to add CORS configuration:

这篇关于Active Storage public_url 不返回 key/filename.extension的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 17:29