I'm trying to upload attachments via AWS s3 presigned url. It is done as a 2 step process . First I created an API for generating a presigned post url and sent to client React App.
class Admin::PresignedUploadController < ApplicationController
before_action :authenticate_user!, only: [:index]
before_action :load_aws_credentials, only: [:index]
before_action :load_bucket, only: [:index]
def index
presigned_url = @s3_bucket.presigned_post(
key: "#{Rails.env}/#{SecureRandom.uuid}/${filename}",
success_action_status: "201",
signature_expiration: (Time.zone.now.utc + 15.minutes)
)
data = { url: presigned_url.url, url_fields: presigned_url.fields }
render json: data, status: :ok
end
private
def load_bucket
@s3_bucket = Aws::S3::Resource.new(
region: ENV["AWS_REGION"],
credentials: @aws_credentials
).bucket(ENV["AWS_BUCKET_NAME"])
end
def load_aws_credentials
@aws_credentials = Aws::Credentials.new(
ENV["AWS_ACCESS_KEY_ID"],
ENV["AWS_SECRET_ACCESS_KEY"]
)
end
end
I'm able to upload the file via a post request to the url and get a response from s3.
<PostResponse>
<Location>https://neeto-chat-staging-v1.s3.amazonaws.com/development%2Fa185e6a8-b4eb-402e-a11a-a2c8ed48bdea%2Fwallpaper-photos-3.jpg</Location>
<Bucket>neeto-chat-staging-v1</Bucket>
<Key>development/a185e6a8-b4eb-402e-a11a-a2c8ed48bdea/wallpaper-photos-3.jpg</Key>
<ETag>"2cbc861b2a9e0c48c7a7edf565f6a509"</ETag>
</PostResponse>
My first problem is that the Location is not accessible and it is showing access denied. I hope it might get solved after giving GET permission in AWS s3.
Is the Location returning the public url of the file?
Do I have to make an additional request to attach it to the model using active record or can it be done automatically using active record?
My schema for attachments:
create_table "active_storage_attachments", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.string "name", null: false
t.string "record_type", null: false
t.uuid "record_id", null: false
t.uuid "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
My model Message has:
has_many_attached :attachments
def get_url(attachment)
Rails.application.routes.url_helpers.rails_blob_path(
attachment, only_path: true
)
end
def get_attachments
if attachments.attached?
self.attachments.attachments.map do |attachment|
{
filename: attachment.filename,
url: get_url(attachment),
id: attachment.id
}
end
end
end
Aucun commentaire:
Enregistrer un commentaire