Cameron
Cameron

Reputation: 28853

Get ActiveStorage blob as a blob

I'm building a Rails app that will allow users to access certain uploaded files directly in the browser but at a different URL to the actual file. This is so that the files can be protected by forcing login.

So for example you might access a file at: domain.com/file/19371da

In the past I have done this by using CarrierWave and then doing to_blob on the file itself and then sending it back using send_data and using data stored about the file in the database:

send_data @file.file.to_blob, stream: false, filename: @file.name, type: @file.mime_type, disposition: 'inline'

However when using the new Active Storage as a potential replacement for CarrierWave I've hit a snag at getting the actual file itself as blob to pass to the send_data method.

e.g.

send_data @file.file.to_blob, stream: false, filename: @file.file.blob.filename, type: @user.file.blob.content_type, disposition: 'inline'

It gives an error undefined method 'to_blob' for #<ActiveStorage::Attached::One:0x007f8f23ca2718>.

How can I get the actual file as a blob in Active Storage?

Upvotes: 2

Views: 10647

Answers (3)

DoubleCompil
DoubleCompil

Reputation: 125

I think you have resolved your problem from now. If not, you can go across has_one_attached and has_many_attached documentation to know how to get Blob from relations – using <my_relation>_blob shortcut.

To get a link for direct-download, you can do this :

 @my_model.file_blob.service_url_for_direct_upload expires_in: 30.minutes

Dependent on how secure you want your system to be, you could just send this short-living url to your signed-in users, it won't expose the original file path (not 100% sure about that).

Upvotes: 1

Cameron
Cameron

Reputation: 28853

So to do this you have to use the download method:

e.g.

send_data @file.file.download, filename: @file.file.blob.filename, type: @user.file.blob.content_type, disposition: 'inline'

Upvotes: 2

Kyle Decot
Kyle Decot

Reputation: 20835

Looking at the source for ActiveStorage::Attached::One it looks like there is a blob method which means you should just be able to call:

@file.file.blob

Upvotes: 3

Related Questions