With introduction of ActiveStorage in Rails 5.2 it has become easier to attach files to ActiveRecord models in Rails. So much so that Paperclip has decided to cease support for their gem and encouraging users to migrate to ActiveStorage for more streamlined solution.

While ActiveStorgae provides straightforward ways to attach files to models using has_one_attached and has_many_attached, the official guides, stackoverflow and online tutorials don’t have an example of a simple uploader to only upload files to a service or local storage in case of development. An example could be a WYSIWYG editor file uploader.

A simple file uploader can be written using ActiveStorage::Blob and url_for. Here we will see an example to upload multiple images using a simple uploader with ActiveStorage.

First we might define route to our controller like:

  # config/routes.rb

  post 'uploader/image', to: 'uploader#image'

In our controller:

  # app/controllers/uploader_controller.rb

  class UploaderController < ApplicationController
    def index; end

    def image
      images_uploader = ImagesUploader.new(files)
      if images_uploader.upload
        flash[:success] = 'Image successfully uploaded.'
        flash[:warning] = 'Image could not be uploaded. Try uploading .png or .jpg'
      redirect_back(fallback_location: root_path)


    def files
      @files ||= params[:files]

We try to avoid putting too much logic in controller. So, we put the ImageUploader in a namespaced directory inside the controllers dir.

  # app/controllers/uploader_controller/images_uploader.rb

  require 'file_upload_service'

  class UploaderController
    # Class to upload images.
    class ImagesUploader
      attr_reader :files

      def initialize(files)
        @files = files

      def upload
        return false if invalid_file_types
        files.each do |file|


      def invalid_file_types
        (files.map(&:content_type) & %w[image/png image/jpeg]).empty?

We place the file upload logic sperate in lib dir. So, that now it is easier if we want to create another uploader for .pdf file type or testing.

  # /lib
  # Used to upload file using ActiveStorage
  class FileUploadService
    def self.upload(file)
        io: file,
        filename: file.original_filename,
        content_type: file.content_type

Create a simple form with file upload fields taking multiple files at once:

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

  <div class="row">
    <div class="col-lg-6 mx-auto m-5">
      <h3>Upload Images</h3>
      <%= form_tag uploader_image_path, method: 'post', multipart: true do %>
        <%= file_field_tag :files, name: 'files[]', multiple: true, class: 'btn btn-primary', required: true %>
        <%= submit_tag 'Upload', class: 'btn btn-primary' %>
      <% end %>
      <small><em>only .png and .jpg</em></small>

And just like that we have a file uploader we can use to upload files straight to our preferred service. Write to me at [email protected] with questions or leave a comment. Cheers!