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
To authorize your app to access s3 bucket you can pass the
AWS#config method. To do this authorization on our application startup we can add a new file in
# config/initializers/s3.rb AWS.config( :access_key_id => 'key', :secret_access_key => 'secret' )
You can either specify your
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.