CarrierWave Upload Multiple Images

Written by kolosek | Published 2020/03/07
Tech Story Tags: carrierwave | image | file | ruby-on-rails | ruby | ruby-on-rails-development | programming | software-development

TLDR CarrierWave is a Ruby gem that provides a simple way to upload files from Ruby applications. This tutorial will show you the necessary steps to enable upload multiple images/files using CarrierWave in Rails 4+ from scratch. A similar procedure can be applied for nested forms. You can generate your migrations using Scaffolding in the Ruby Gemfile. This will generate a full set of model, views and controller, and a test suite for each of the above. The next step is to add the following to your PostAttachment model.via the TL;DR App

When you are building a web application, you definitely want to add an option for image uploading as well. In this tutorial, we will show you the necessary steps to enable upload multiple images/files using CarrierWave in Rails 4+ from scratch. A similar procedure can be applied for nested forms.
Step 1: In the gem file
CarrierWave is a Ruby gem that provides a simple and extremely flexible way to upload files from Ruby applications. You will need to add these gems to the Gemfile and run
bundle install
gem 'carrierwave'

Step 2: Setting up CarrierWave

The first step to configure CarrierWave it to run the following command:
rails generate uploader Avatar
This will create a new directory called uploaders in the app folder and a file inside called avatar_uploader.rb.
class AvatarUploader < CarrierWave::Uploader::Base
  storage :file
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end
  def default_url
    "/images/fallback/" + [version_name, "default.png"].compact.join('_')
  end
end
store_dir
- You can modify the default directory to change where uploaded files will be stored.
default_url
- It is the path to the default image, you can use this image if no other image has been selected.

Step 3: Generate your migrations

You can generate your migrations using Scaffolding in Rails. This will generate a full set of model, views and controller, and a test suite for each of the above. It is the most simple way to get your project up and running.
  • rails g scaffold post title:string
  • rails g scaffold post_attachment post_id:integer avatar:string
  • rake db:migrate

Step 4: Edit Models

Once scaffolding finishes generating the files you can start editing your models.
You want to be able to create post and post_attachment in one go. To do this you need to add the following to
`post.rb`
:

post.rb

    class Post < ActiveRecord::Base
     has_many :post_attachments
     accepts_nested_attributes_for :post_attachments
    end
`accepts_nested_attributes_for :post_attachments`
- Nested attributes allow you to save attributes on associated records through the parent.
The time has come to mount your uploader. Navigate to your PostAttachment model and add
`mount_uploader :avatar, AvatarUploader`
to the file.

post_attachment.rb

    class PostAttachment < ActiveRecord::Base
       mount_uploader :avatar, AvatarUploader
       belongs_to :post
    end

Step 5: Modify your Controller

The next step is to modify the
`post_controller`
to accept those new nested attributes.

post_controller.rb

def show
  @post_attachments = @post.post_attachments.all
end
def new
  @post = Post.new
  @post_attachment = @post.post_attachments.build
end
To make sure that
`post_attachments`
is ready to be created once the new post is done, you will need to build it with
`@post.post_attachments.build`
.
 def create
       @post = Post.new(post_params)
       respond_to do |format|
         if @post.save
           params[:post_attachments]['avatar'].each do |a|
              @post_attachment = @post.post_attachments.create!(:avatar => a,     :post_id => @post.id)
           end
           format.html { redirect_to @post, notice: 'Post was successfully     created.' }
         else
           format.html { render action: 'new' }
         end
       end
     end
To help the nested attributes reach the model, you will need to add the following to the post_params method in the PostController.
private
def post_params
  params.require(:post).permit(:title, post_attachments_attributes: 
  [:id, :post_id, :avatar])
end

Step 6: View layout

For the last step to finish out application you will need to edit the view to allow us to upload new images. You can do this by adding the following line:
<%= p.file_field :avatar, :multiple => true, name:     "post_attachments[avatar][]" %>

views/posts/_form.html.erb

<%= form_for(@post, :html => { :multipart => true }) do |f| %>
       <div class="field">
         <%= f.label :title %><br>
         <%= f.text_field :title %>
       </div>
       <%= f.fields_for :post_attachments do |p| %>
         <div class="field">
           <%= p.label :avatar %><br>
           <%= p.file_field :avatar, :multiple => true, name:     "post_attachments[avatar][]" %>
         </div>
       <% end %>
       <div class="actions">
         <%= f.submit %>
       </div>
    <% end %>
Thank you for reading!
Previously published at https://kolosek.com/carrierwave-upload-multiple-images/

Written by kolosek | CEO @ Kolosek.com
Published by HackerNoon on 2020/03/07