Rectangle 27 0

Carrierwave, Rails 4, and Multiple Uploads?


<%= 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 %>

   <% if params[:controller] == "post" && params[:action] == "edit" %> 
     <% @post.post_attachments.each do |p| %>
       <%= image_tag p.avatar, :size => "150x150" %>
     <% end %>
   <% end %>

   <div class="actions">
     <%= f.submit %>
   </div>
<% end %>
<p id="notice"><%= notice %></p>

<p>
  <strong>Title:</strong>
  <%= @post.title %>
</p>

<% @post_attachments.each do |p| %>
  <%= image_tag p.avatar_url, :size => "150x150" %>
  <%= link_to "Destroy", p, method: :delete %>
<% end %>

<%= link_to 'Edit', edit_post_path(@post) %> |
<%= link_to 'Back', posts_path %>
class Post < ActiveRecord::Base
   has_many :post_attachments
   accepts_nested_attributes_for :post_attachments
end
class PostAttachment < ActiveRecord::Base
   mount_uploader :avatar, AvatarUploader
   belongs_to :post
end
def show
   @post_attachments = @post.post_attachments.all
end

def new
   @post = Post.new
   @post_attachment = @post.post_attachments.build
end

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

 def update
   respond_to do |format|
     if @post.update(post_params)
       params[:post_attachments]['avatar'].each do |a|
         @post_attachment = @post.post_attachments.create!(:avatar => a, :post_id => @post.id)
       end
     end
  end

  def destroy
    @post.destroy
    respond_to do |format|
      format.html { redirect_to @post }
      format.json { head :no_content }
    end
  end


 private
   def post_params
      params.require(:post).permit(:title, post_attachments_attributes: [:id, :post_id, :avatar])
   end
gem 'carrierwave'
bundle install
rails generate uploader Avatar
rails g scaffold post title:string
rails g scaffold post_attachment post_id:integer avatar:string

rake db:migrate
rails new multiple_image_upload_carrierwave

This is solution to upload multiple images using carrierwave in rails 4 from scratch

Essentially I'm wondering what the post_controller.rb would look like to correctly edit and delete the attachments?

Great post @SSR, only multiple upload I've managed to get working. Don't suppose you'd be able to expand it slightly? In it's current form the files aren't deleted when the parent model is. (Or don't for me), and I'm wondering how I'd go about editing the post and it's attachments together.

In rails 3 no need to define strong parameters and as you can define attribute_accessible in both the model and accept_nested_attribute to post model because attribute accessible is deprecated in rails 4.

thanks, it helps me I meant the idea!

Note
Rectangle 27 0

Carrierwave, Rails 4, and Multiple Uploads?


CarrierWave doesn't support multiple uploads. It's designed to associate a single file with a single field.

If you want multiple uploads, you need either multiple fields (each with a CarrierWave uploader), or multiple objects each with a single CarrierWave uploader field.

Just to be clear: Your solution uses multiple objects (post_attachments), each with a single uploader, and demonstrates the manual work necessary to get parameters assigned properly for use of the "multiple" attribute. You've demonstrated how to do what the OP wanted, but it doesn't make any part of the above false.

That is not true. it support multiple upload within single field. see my answer. carrierwave provides much more.

The multiple attribute is also unsupported, so if you use it, it's entirely up to you to get the parameters assigned properly.

Time progresses ever onwards. The Earth spins and gradually changes, and CarrierWave now supports multiple-file upload natively. However the CarrierWave way of doing it is an ugly hack (referencing all the files in one field using an array) that I would avoid using. Go with SSR's solution instead.

Note