This article will discuss how to integrate AWS S3 in a Ruby on Rails application using ActiveStorage.
Start by creating an application, installing active storage, generating a scaffold and migrating.
1
2
3
4
rails new aws-s3-tutorial
rails active_storage:install
rails generate scaffold User name
rails db:migrate
Use the dot-env
gem for storing API keys in the .env
file. Install dot-env
by adding it to Gemfile
:
1
2
gem "dotenv-rails"
gem "aws-sdk-s3", require: false
Now run the command bundle install
.
Next, create a free AWS account and get the API keys. To get the secret keys, first click on S3.
Now create a bucket.
Next, add a user to the newly created bucket.
After creating a user, grant them access to S3.
Here you will find the keys.
Add two files, .env
and .env.sample
, in the project root and add .env
in the .gitignore
because we don’t want the secret keys to be visible in git or anywhere else.
Add this to your .env
file:
1
2
3
AWS_ACCESS_KEY_ID=youraccesskeyid
AWS_SECRET_ACCESS_KEY=yoursecretaccesskey
AWS_BUCKET=yourbucket
Of course, you need to replace these dummy keys with your original ones. Also, add dummy values to .env.sample
so as to send this file to git.
1
2
3
AWS_ACCESS_KEY_ID=dummyaccesskeyid
AWS_SECRET_ACCESS_KEY=dummysecretaccesskey
AWS_BUCKET=dummybucket
Configure the config/storage.yml
file with the following line:
1
2
3
4
5
6
7
amazon:
service: S3
access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %>
secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
region: “your selected region here”
bucket: <%= ENV['AWS_BUCKET'] %>
Tell ActiveStorage which service to use for image uploads by putting this line in the production.rb
file:
1
config.active_storage.service = :amazon
Make sure you have this line in your application.js file:
1
require("@rails/activestorage").start()
Now that the basic setup of S3 is done, let’s move on to the implementation.
In app/models/user.rb
:
1
2
3
4
5
# app/models/user.rb
class User < ApplicationRecord
has_one_attached :avatar
end
Add this to the _form.html.haml
partial:
1
2
3
4
5
<div class="field">
<%= form.label :avatar %>
<%= form.file_field :avatar %>
</div>
The view that displays the image (such as show.html.haml
) needs to include the following code:
1
2
3
<div>
<%= image_tag @user.avatar if @user.avatar.present? %>
</div>
In your app/controllers/users_controller
, permit avatar.
1
2
3
def user_params
params.require(:user).permit(:name, :avatar)
end
Before running and testing, export the environment variables:
1
2
3
export AWS_ACCESS_KEY_ID=youraccesskeyid
export AWS_SECRET_ACCESS_KEY=yoursecretaccesskey
export AWS_BUCKET=yourbucket
S3 is now installed and configured. Happy uploading!