2

I'm using Activestorage. I want to retrieve the S3 key to hand off to a microservice. I don't want to download the blob or anything like that in the Rails app, I just want to provide the file path/key in an API request.

service_url is overkill because I already have access the bucket in the microservice, not to mention the fact that these are large files and I don't need to transfer them unnecessarily.

What are my options?

t56k
  • 6,769
  • 9
  • 52
  • 115
  • If you are in need of multiple API keys for the microservice, you could consider passing it in the POST body of the API request, but this is also a security risk. Aren't you able to set the API key as an ENV var in the microservice? – bo-oz May 14 '19 at 05:42
  • Sorry, not the access keys, the key that refers to a specific file, i.e., `bucket/folder/image.jpg`. – t56k May 14 '19 at 05:43
  • Yeah, that you would definitely pass in the POST body or GET parameters. If the microservice also has access to the database and it is also a RoR application, you could also configure the endpoint in a way that it is already related to the ActiveStorage object. – bo-oz May 14 '19 at 05:47
  • It has S3 access but it's not a Rails app. I just need the Rails method to expose whatever the file-key is on S3. – t56k May 14 '19 at 05:48
  • So just provide it with the location of the S3 file. You can add any parameter to a GET or POST request. Just pull that from the request and perform your operations. – bo-oz May 14 '19 at 05:50
  • I'm not sure you're catching my problem. I need the Rails-app side method that returns the file key from S3. I know how to get it to the microservice once I have it, I just don't know how to get it from the Rails app itself, like, even internally to display in a view or the console. – t56k May 14 '19 at 06:04
  • 1
    I think this is what you are looking for? https://stackoverflow.com/a/49803251/891359 – bo-oz May 14 '19 at 06:10

2 Answers2

6

Using service_url is not only overkill, it also runs into issues if you try to use it outside of the ActiveStorage controller, as described here.

Better is ActiveStorage#key, which for S3 will return just the S3 key to your object. It is still not what you're supposed to use for public values - ActiveStorage#signed_id gives you the railsy key. But if you want the raw S3 key (as I did for a service API), key works and doesn't complain outside of the controller.

So in your case:

def logo_key_on_s3
  logo.key
end

should work.

Luke Abel
  • 243
  • 2
  • 9
  • 1
    You're right, I must have tried that when I was looking for the filename-as-key. Cheers. – t56k May 17 '19 at 22:09
  • I thought this key is for something else, but it is a replacement of folder path to s3 by `ActiveStorage`. Great! – Abhi Aug 30 '19 at 15:56
1

So while @bo-oz did link to helpful discussion it didn't really answer the question, so, to retrieve the key under which the file is stored on S3:

class User < ApplicationRecord
  has_one_attached :logo

  def logo_key_on_s3
    logo&.service_url&.split('?')&.first
  end
end

This just generates a service URL and strips out all the access tokens, expiry, etc., which is all I need since the microservice already has bucket access.

t56k
  • 6,769
  • 9
  • 52
  • 115