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!