In my last blog post I explained how to upload file via ajax. In that the file is store in the application server itself. But what if we want to store file in our s3 bucket. We can use aws-sdk
gem to do it.
Add gem to Gemfile
# Gemfile
gem 'aws-sdk'
As usual after adding gem to Gemfile
do bundle install
.
Configure AWS
To authorize your app to access s3 bucket you can pass the key
and secret
to AWS#config
method. To do this authorization on our application startup we can add a new file in config/initializers
folder.
# config/initializers/s3.rb
AWS.config(
:access_key_id => 'key',
:secret_access_key => 'secret'
)
You can either specify your key
and secret
in s3.rb
or load it from custom configuration file. The latter one is recommended.
Upload to s3
Now we have configured and authorized our application to access s3 buckets. Now we can start working on uploading files. Since uploading to s3 can be from any controller, I like to move the functionality to lib
folder as a separate custom library.
# lib/s3_store.rb
class S3Store
BUCKET = "app-uploads".freeze
def initialize file
@file = file
@s3 = AWS::S3.new
@bucket = @s3.buckets[BUCKET]
end
def store
@obj = @bucket.objects[filename].write(@file.tempfile, acl: :public_read)
self
end
def url
@obj.public_url.to_s
end
private
def filename
@filename ||= @file.original_filename.gsub(/[^a-zA-Z0-9_\.]/, '_')
end
end
Now we have separate s3_store
library to do task related to s3 bucket. Since our library is in lib
folder, rails by default won’t load it. To reload the s3_store.rb
in development we need to add lib
folder to autoload paths. This will also ensure that rails will autoload our library and we don’t need to write a separate require
for it.
ok, go ahead and use the library in our controller, to upload files to s3 bucket.
# app/controllers/some_controller.rb
def image
begin
image = S3Store.new(params[:upload][:image]).store
#...
rescue Exception => e
#...
end
end
Since we return self
from store method, you can use image.url
to get the public url of the file uploaded. This can be used to store to db for reference.