In this chapter, you will learn about the Active Storage framework in Ruby on Rails. Active Storage was introduced in the version 6.1 of Rails. Active Storage enables uploading and attaching files (e.g., images, videos, PDFs) to the Rails models. It supports storing files on local disk as well in the cloud like Amazon S3, Google Cloud Storage, etc.
Active Storage handles tasks such as −
- Uploading files from forms
- Attaching files to models (has_one_attached / has_many_attached)
- Serving, previewing, and transforming files
Note that you may have to install other gems such as poppler or muPDF for PDF previews, or ImageMagick for image transformations (for example creating thumbnails). Image analysis and transformations also require the image_processing gem.
To enable the Active Storage support in a Rails application, you need to install the component and run the migrations to create the required tables.
Set up Active Storage
Let us start by creating a new Rails app
rails newUploaderApp cd UploaderApp
As you enter the application folder, install active_Storage component and run migration.
rails active_storage:installCopied migration 20250408064642_create_active_storage_tables.active_storage.rb from active_storage rails db:migrate
The terminal shows that the following tables are created:
========20250408064642CreateActiveStorageTables: migrating ==============-- create_table(:active_storage_blobs,{:id=>:primary_key})->0.0045s -- create_table(:active_storage_attachments,{:id=>:primary_key})->0.0033s -- create_table(:active_storage_variant_records,{:id=>:primary_key})->0.0022s ======20250408064642CreateActiveStorageTables: migrated (0.0134s)======
Tables Created Due to Migration
Following tables are created as a result of the migration:
- active_storage_blobs – This table Stores metadata and unique references to uploaded files (like a pointer to the file stored on disk or in cloud). Each row represents a unique file. The fields in this table include filename, content_type and byte_size along with the Timestamp of creation.
- active_storage_attachments – This table is used to join your model (like User) to the actual file (Blob). Each row represents one attachment between a model and a file.
- active_storage_variant_records – The purpose of this table is to Cache the image variants (like thumbnails or resized images).
The process of reading/writing is taken care of by Rails by providing abstractions in the form of methods like user.profile_picture.attach(…) or display image_tag user.profile_picture.
Rails stores uploaded files in the storage subfolder of the application folder in development and test environments in production, the config/storage/production.yml file is used to specify the corresponding bucket or container of the provider such as Amazon, Google or Azure etc.
Scaffold a User model
To demonstrate how Rails performs file uploading, let us quickly scaffold a User resource with username and email as the model attributes.
rails generate scaffold User username:string email:string db:migrate
Edit the User model to add profile_picture attribute (in app/models/user.rb)
classUser<ApplicationRecord has_one_attached :profile_pictureend
To permit File Parameter in Controller, update UsersController in user_params method:
# Only allow a list of trusted parameters through.defuser_params params.require(:user).permit(:username,:email,:profile_picture)end
Edit the views
The scaffolding has already created a form to enter a new user. You will need to add a file input type to it:
<%= form_with(model: user) do |form| %> <% if user.errors.any? %><div><%= form.label :username, style: "display: block" %><div style="color: red"><h2><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2> <ul> <% user.errors.each do |error| %> <li><%= error.full_message %></li><%end%> </ul></div><%end%>
</div><div><%= form.label :email, style: "display: block" %><%= form.text_field :username%>
</div><div><%= form.label :profile_picture, style: "display: block" %><%= form.text_field :email%>
</div><div><%= form.submit %> </div><%end%><%= form.file_field :profile_picture%>
The code shown in bold needs to be added.
You must make changes to the show view too. Make sure that the show.html.erb file in app/views/users folder has the following code:
<p style="color: green"><%= notice %></p><p><strong>Username:</strong> <%= @user.username %> </p><p><strong>Email:</strong> <%= @user.email %> </p> <% if @user.profile_picture.attached? %> <%# for Active Storage %> <p><strong>Profile Picture:</strong><br></p> <% end %> <div> <%= link_to "Edit this user", edit_user_path(@user) %> | <%= link_to "Back to users", users_path %> <%= button_to "Destroy this user", @user, method: :delete %> </div><%= image_tag @user.profile_picture %>
And thatâs it. Incorporate all the changes suggested above and run the Rails server. The /users/new URL opens up a form to add a new user.

Click on the Choose File button, navigate to the desired file and then click the Create User button. Rails responds with a confirmation page, displaying the profile picture you uploaded.

Leave a Reply