Active Storage public_url not returning key/filename.extension

后端 未结 1 1518
臣服心动
臣服心动 2021-01-28 20:39

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 stru

相关标签:
1条回答
  • 2021-01-28 21:06

    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:

    0 讨论(0)
提交回复
热议问题