# Active Storage in Rails ![image alt](https://media.giphy.com/media/8cEFp9dQCcE8M/giphy.gif "title") ## Overview Active Storage is a new feature of Ruby on Rails 5.2. Active Storage allows Rails developers to manage file uploads, cloud storage, and document management tied to models throughout apps. It attaches pointers to the Active Record object and will upload it asynchronously. :::info Rails 5.2 and later: Active Storage included Rails 5.1.6 and older: requires `gem` ::: ## Some Features ### Mirror Service Allows syncing of files between multiple cloud storage services. For example, in `config/storage.yml` we have this block: ```ruby development: service: Mirror primary: amazon mirrors: - azure - google ``` In this example, the mirror service would first upload files to **Amazon** since it is set as the primary. Then, it would push the same files to **Azure** and **Google Cloud**. File removal takes place in the same order. This can be helpful when switching between cloud services or when creating backups. ### Direct Uploads Since Active Storage comes with a Javascript library (`activestorage.js`) we can upload files from the front end of our site to cloud storage directly. Some events used by this library are: ```bash direct-upload:start direct-upload:initialize direct-upload:progress ``` ### Asynchronous Upload Doesn’t require adding any background job to upload files asynchronously. It uses Active Job to upload files to the cloud. ## Installation 1. Within your Rails app, look in the following folders: `config/environments/development` and `config/environments/production` Ensure the following is included: `config.active_storage.service = :local`. This tells the app to save your uploads locally. 2. To install into your application run: ```bash rails active_storage:install ``` This generates an `active_storage_blobs` and an `active_storage_attachments` table. Run: ```bash rails db:migrate ``` Once you configure it you can go to your models, and define your attachments. If you have a model for User and need to upload the profile picture of that user and allow them to upload other files: ```ruby class User < ApplicationRecord has_one_attached :profile_picture has_many_attached :uploads end ``` The `has_one_attached` method maps a one to one relationship between the Active Record Object and the uploaded file. The `has_many_attached` maps a one to many relationship. When you have a form for the user using form_with you can simply add fields for the attachments within that form: ```ruby <%= form.file_field :profile_picture %> <%= form.file_field :uploads, multiple: true %> ``` We also have to create an action in the user controller that takes in the user params, here we just added :profile_picture and :uploads into it: ```ruby def create @user = User.create(user_params) end private def user_params params.require(:user).permit(:email, :password, :profile_picture, uploads: []) end ``` *Notice uploads parameter has many so we use array notation here. One cool thing about this, is that if you go to the index page that might list the users, all you have to do to display an image is say `<%= image_tag @user.profile_picture %> ` ## Demo ## Additional Resources * [Active Storage Overview](https://guides.rubyonrails.org/active_storage_overview.html) * [Active Storage README](https://github.com/rails/rails/blob/d3893ec38ec61282c2598b01a298124356d6b35a/activestorage/README.md) * [DEANOUT on YouTube: Active Storage Tutorial Series](https://www.youtube.com/channel/UCRQv-3VvPT9mArF5RfrlpKQ) * [Tutorial on how to use Active Storage on Rails 5.2](https://www.engineyard.com/blog/active-storage)