Skip to content

Instantly share code, notes, and snippets.

@TigerWolf
Created February 29, 2020 07:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TigerWolf/b68259e53e3767b25f2bfe40e1200ed5 to your computer and use it in GitHub Desktop.
Save TigerWolf/b68259e53e3767b25f2bfe40e1200ed5 to your computer and use it in GitHub Desktop.

How to use ActiveStorage in Rails 6 to upload files to s3

Activestorage is a layer inside of rails that helps you connect with cloud services like AWS. Its also connects to other providers like Azure and Google cloud. You can use it to run tasks as well, but in this guide I will focus on uploading a file to s3 and displaying it inside your rails app.

Note: Have you thought about the environmental impact of the servers you use? Check out this link to look at the environmental impact of the cloud servers you use.

Setup

In order to use ActiveStorage you will need to setup a database. ActiveStorage should be installed with rails. You can use the rake task bin/rails active_storage:install to generate some migrations that you can run on your database. Run these with bin/rails db:migrate. This will create two tables, active_storage_blobs and active_storage_attachments where the file information and attachments are stored.

One this is installed and run against your database, you will need the s3 gem. You can install this by adding gem "aws-sdk-s3", require: false to your gem file.

Rails should have automatically generated a storage configuration file for you with some examples. You will need to modify the example configuration file at config/storage.yml and uncomment the amazon section, I also commented the local section:

https://gist.github.com/6cac2fe213a8f2eab57abb50809b00c6

You will now need to get your own access key and secret key. You can get these details by logging into Amazon and follow this guide: https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/setup-config.html When you have these you can put them into your secrets for your application.

Rails 6 has a great way of storing credentials. You can use this command to add your secret key and access key: rails credentials:edit --environment production. This should open your credentials in your editor. You can add them like so:

https://gist.github.com/7917d220e491e0650f8708d6f7056ddf

If you want to test this in your local development environment, you will need to change the configuration for your development environment like so:

https://gist.github.com/46e19c6e374db0692ea76c9e60abf5cd

Now we will generate the models needed that will have the images attached to them. First start by creating a profile model. We can use the rails generators to create a scaffold to help us get up and running.

rails g scaffold profile name:string description:text

Now, in your profile model, add an attachment. This will create a relationship to those tables we added before

https://gist.github.com/41e65daa498b1df3b78ade13d99042b6

We will also need to allow the controller to accept this new parameter, so in the controller strong params add:

https://gist.github.com/bc305809100ca0d77e1ac48f06bd5a8c

Now lets add the image to the view. We can do this by adding it to the form to allow for the image to be uploaded:

https://gist.github.com/1ab1d7b44dd07e6cdfa4c35e2727be69

and then to display the image after it has been created or shown:

https://gist.github.com/a6c26c06fd77c915549f1cf8c7a201c3

That should be everything you need! Now you can run rails s and go to http://localhost:3000/profiles/new in your browser and create a new profile with an image.

Under the hood, rails uses ActiveStorage::BlobsController and ActiveStorage::DiskController to serve the files up when displaying them in the browser. This controller takes the url that is requested in the controller and redirects it the asset stored on s3.

You can find my example code at: https://github.com/TigerWolf/rails6_activestorage

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment