paint-brush
Uploading Files Into Ruby On Rails ActiveStorageby@theophile-kango
1,870 reads
1,870 reads

Uploading Files Into Ruby On Rails ActiveStorage

by Theophile KangoAugust 17th, 2020
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

The author has created a series of questions about how to create a virtual virtual reality experience. The questions include how to use the virtual world to create your own virtual reality world. The author is inspired by the idea of virtual reality in the form of "virtual reality" and "reality in the world" to create virtual reality. To create your virtual world, visit CNN.com/Heroes for a virtual reality tour of your virtual reality story. Visit http://www.cnn.org/virtualreality.com for details.

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - Uploading Files Into Ruby On Rails ActiveStorage
Theophile Kango HackerNoon profile picture

Introduction

When storing static files in Rails, the first toolsets I reach for are 3rd party gems like: CarrierWave or Paperclip (before they deprecated it in favour of Active Storage). Active Storage was introduced with Rails 5.2. 

Active Storage facilitates uploading files to a cloud storage service like Amazon S3, Google Cloud Storage, or Microsoft Azure Storage and attaching those files to Active Record objects. It comes with a local disk-based service for development and testing and supports mirroring files to subordinate services for backups and migrations.

Using Active Storage, an application can transform image uploads with ImageMagick, generate image representations of non-image uploads like PDFs and videos, and extract metadata from arbitrary files.

In this article, we will focus on how to make the validation of active storage's files by creating a simple app.

Go in the terminal and generate a new app

rails new app

After cd in the app folder crated, let's generate a simple blog app with the scaffold command.

rails g scaffold Post title:string content:text

When the process finished don't forget to migrate

rails db:migrate

We can lunch the server now

rails server

And by visiting the

localhost:3000/posts/index
in our browser, we can see the application running.

Let's set the routes to posts/index by editing the

config/routes.rb
file

#config/routes.rb

Rails.application.routes.draw do
  resources :posts
  root to: 'posts#index'
end

Let's now add the image to our Post with active storage.

Set up

First, we need to install active storage in our project. We will need to run this command on the terminal lines

rails active_storage:install

After running this command, Rails generates a migration for you. Upon inspection of that migration, and creates 2 different tables:

active_storage_blobs 
is up first, it contains information about files like metadata, filename, checksum, and so on.

The next table, 

active_storage_attachments
, stores the name of any file attachment as well as the record, which is also a polymorphic association. Why is that important? It allows you to use file attachments on any model without cluttering your model's migrations with table columns specifically for file data.

Don't forget to run the migration command At the end

rails db:migrate

Adding the image to the Model, View and Controller

By visiting our

app/models/post.rb
We will attach the image to our post

#app/models/post.rb

class Post < ApplicationRecord
    has_one_attached :image
end

We will again need to add the image in our controller just at the end in the post_params method add the image to the properties of the model.

  
 #app/controller/posts_controller.rb

 def post_params
      params.require(:post).permit(:title, :content, :image)
 end

We will now go in our views and add the image.

In the

app/views/posts/_form.html.erb
we will be editing the file by adding a new class after the content.

#app/views/posts/_form.html.erb

<div class="field">
  <%= form.label :image %>
  <%= form.file_field :image %>
</div>

Now we need to load the image in the index and show

#app/views/posts/index.html.erb

<% if post.image.attached? %>
    <td><%= image_tag post.image %></td>
<% end %>
#app/views/posts/show.html.erb

<p>
  <% if @post.image.attached? %>
    <%= image_tag @post.image %>
  <% end %>
</p>

And voila, we can add the image to the post. But what if we want to have the image associate to each post?

In this case, we will need to validate our image so that the user can not create a post without an image.

Let's first validate our title and content fields

# app/models/post.rb

class Post < ApplicationRecord
    has_one_attached :image
    validates :title, :content, presence: true
    validates :title, length: {minimum:5, maximum:25}
    validates :content, length: {minimum:10, maximum:50}
end

By editing our

post.rb
file, we prevent the user to submit an empty title and empty content field. He can't also submit the title with content less than 5 or more than 25 characters, as well as the content, can't have more than 50 or less than 10 characters.

Validation with Active Storage

We've now validated our title and content, but we need again to prevent the user to create a post without an image associated with it.

It is very simple, we can do it by adding this one line. But before that, we need first to add the

gem 'active_storage_validations'
in the Gemfile and run
bundle install
after.

# app/models/post.rb

validates :image, attached: true, content_type: %i[png jpg jpeg]

We prevent the user to add files of types different from png, jpg and jpeg and we say that the image must be attached to the post. So he can't submit a post without an associated image.

Restart the server to see the changes.

Voila, we reach our goal, now the user can not submit a Post with an empty image.