# Local ActiveStorage Development With Rails 7

> Set up ActiveStorage on your local developer environment with Rails 7.

- Canonical: https://dennisokeeffe.com/blog/2022-04-07-local-activestorage-development-with-rails-7
- Published: 2022-04-07
- Updated: 2022-04-07
- Tags: ruby, ruby-on-rails

This post will cover the basics of getting up and going with ActiveStorage by enabling it, then showing a demonstration of a basic form to attach an image and then view that image on that new user profile page.

Source code can be found [here](https://github.com/okeeffed/demo-local-activestorage-development)

## Prerequisites

1. Basic familiarity with setting up a [new Rails project](https://guides.rubyonrails.org/getting_started.html).
2. Have an image ready to go.
3. ActiveStorage requires different dependencies depending on the content you are serving.

For (3), on Mac I used Brew to install a few dependencies required for images, videos and PDFs (for further use) but none should be required for this tutorial.

```s
# Only imagemagick is needed, but the
# others are for video previews and
# PDF previews. Mac only.
$ brew install imagemagick poppler ffmpeg
```

## Getting started

We will use Rails to initialize the project `demo-local-activestorage-development`:

```s
# Create a new rails project
$ rails new demo-local-activestorage-development
$ cd demo-local-activestorage-development

# Init active storage
$ bin/rails active_storage:install
$ bin/rails db:migrate

# Generate the model we will use
$ bin/rails g model User name:string avatar:attachment
$ bin/rails db:migrate

# Generate controller with routes we will use for demo
$ bin/rails g controller Users index create show new
```

> Note: Since we are using integers and not UUIDs, we did not have to change anything on the column type.

Our project is now ready to start working with.

At this point, we could update our `config/storage.yml` for our production storage, but we won't do that for our example as `local` and `test` are ready.

The next step will be to populate the routes, controllers and views.

## Updating our routes

In `config/application.rb`:

```rb
Rails.application.routes.draw do
  resources :users

  # Defines the root path route ("/")
  # root 'users#index'
end
```

We aren't explicitly denying any routes at this point since it is a contrived demo, but you could put `resources :users, only: [:index, :create, :show, :new]` in the `config/routes.rb` file if you wanted to lock it down.

## Updating the controllers

Next, we want to fill in our `create` and `show` actions to create a new user and show the user's profile information.

In `app/controllers/users_controller.rb`:

```rb
class UsersController < ApplicationController
  def index; end

  def new; end

  def create
    user = User.create!(name: params[:name], avatar: params[:avatar])
    session[:user_id] = user.id
    redirect_to user_path(user)
  end

  def show
    @user = User.find(params[:id])
  end
end
```

`create` will be invoked when we submit our form from the `new` view and `show` will return the specific user information for our `show` view.

## Creating our views

The controller scaffold autogenerated our views for us, but we need to update them to include our form and our profile page.

Under `app/views/users/new.html.erb`:

```erb
<h1>Users#new</h1>
<%= form_with url: "/users" do |form| %>
  <div>
    <%= form.label :name, "Name" %>
    <%= form.text_field :name %>
  </div>
  <div>
    <%= form.label :avatar, "Avatar" %>
    <%= form.file_field :avatar %>
  </div>
  <div>
    <%= form.submit "Submit" %>
  </div>
<% end %>
```

In the above, we submit the form as POST to the `/users` route which will hit `create` in our `UsersController`.

Next, for `app/views/users/show.html.erb`:

```erb
<h1>Users#show</h1>
<%= image_tag @user.avatar %>
```

We will just display the profile picture for our user.

## Testing our application

At this stage, we are ready to demo our project.

Start the Rails server with `bin/rails s` and head to `http://localhost:3000/users/new` to see the form.

![New user form](https://cdn.dennisokeeffe.com/assets/2022-04-07-local-activestorage-development-with-rails-7/1-new.webp)

Fill out the (beautiful) form with a name, upload an image and submit. Our `create` controller will create the new user, then redirect us to the `show` page for that user.

At this user page, you can now see the image we uploaded!

![Show user](https://cdn.dennisokeeffe.com/assets/2022-04-07-local-activestorage-development-with-rails-7/2-show.webp)

Awesome! If you wanted a little more detail on the attachment, you can always jump onto the Rails console `bin/rails c` and play around to see the attachment:

```rb
irb(main):001:0> User.first.avatar
  User Load (0.2ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=>
#<ActiveStorage::Attached::One:0x00007f82f04f7840
 @name="avatar",
 @record=
  #<User:0x00007f82f04f7908
   id: 1,
   name: "Dennis",
   created_at: Thu, 07 Apr 2022 09:37:37.993575000 UTC +00:00,
   updated_at: Thu, 07 Apr 2022 09:37:38.052556000 UTC +00:00>>
```

## Summary

Today's post demonstrated how to set up ActiveStorage with Rails 7 and test it out with a basic form.

This only covered the local storage phase, and not actually the setup with anything else like AWS S3 or Google Cloud Storage. They would be your next steps.

## Resources and further reading

- [Rails getting started](https://guides.rubyonrails.org/getting_started.html)
- [Source code](https://github.com/okeeffed/demo-local-activestorage-development)

_Photo credit: [`chiro`](https://unsplash.com/@chiro)_
