Thomas V.

2 minute read

About a month ago I cut my hours back from full time to part time, and ever since I’ve been working on building a product that is yet to launch called OrderDeck.

One of OrderDeck’s primary functions is that a user must be able to upload file attachments to custom orders and conversations.

When a file is uploaded the user is notified and they can either preview or download the file.

All of our infrastructure runs on Amazon Web Services: file uploads get sent directly from the browser to S3 using CORS, processed on EC2, and the uploaded to a different S3 bucket.

Depending on the file type, we may want to display the file directly in the browser or have it download straight to disk.

Some of the ways I saw people accomplishing direct downoads seemed rather ineffecient, especially considering how easy the AWS SDK makes this task.

Given a media object stored in your database with an s3_bucket and a s3_key:

class Media < ActiveRecord::Base
  def download_url
    s3 = AWS::S3.new
    bucket = s3.buckets['the_name_of_your_bucket']
    object = bucket.objects[s3_key]
    object.url_for(:get, {
      expires: 10.minutes,
      response_content_disposition: 'attachment;'
    }).to_s
  end
end

With #download_url in place, we can now setup a controller that can easily redirect to your S3 object with an Attachment dispoition:

class MediaObjectsController < ApplicationController
  def download_media
     @media = MediaObject.find(params[:id])
     redirect_to @media.download_url
  end
end

It’s worth noting to properly setup and configure the aws-sdk gem you’ll have to create a new initializer in your project:

AWS.config(access_key_id: Rails.application.secrets.access_key_id, 
           secret_access_key: Rails.application.secrets.secret_access_key, 
           region: 'us-east-1')
comments powered by Disqus