This post shows how to use carrierwave gem to upload multiple files in Rails 4
Let suppose the following scenario. We have multiple projects and each project can have multiple screenshots.
In project.rb
class Project < ActiveRecord::Base has_many :screenshots accepts_nested_attributes_for :screenshots, :allow_destroy => true end
In screenshot.rb
class Screenshot < ActiveRecord::Base belongs_to :project mount_uploader :image, ScreenshotUploader end
In project_controller.rb
class ProjectsController < ApplicationController
# GET /projects/new
def new
@project = Project.new
@project.screenshots.new
end
# GET /projects/1/edit
def edit
@project.screenshots.new
end
# POST /projects
# POST /projects.json
def create
@project = Project.new(project_params)
respond_to do |format|
if @project.save
if params[:screenshots_attributes]
params[:screenshots_attributes].each do |screenshot|
@project.screenshots.create(image: screenshot[:image])
end
end
format.html { redirect_to @project, notice: 'Project was successfully created.' }
format.json { render :show, status: :created, location: @project }
else
format.html { render :new }
format.json { render json: @project.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /projects/1
# PATCH/PUT /projects/1.json
def update
respond_to do |format|
if @project.update(project_params)
if params[:screenshots_attributes]
params[:screenshots_attributes].each do |screenshot|
@project.screenshots.create(image: screenshot[:image])
end
end
format.html { redirect_to @project, notice: 'Project was successfully updated.' }
format.json { render :show, status: :ok, location: @project }
else
format.html { render :edit }
format.json { render json: @project.errors, status: :unprocessable_entity }
end
end
end
# DELETE /projects/1
# DELETE /projects/1.json
def destroy
@project.destroy
respond_to do |format|
format.html { redirect_to projects_url, notice: 'Project was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_project
@project = Project.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def project_params
params.require(:project).permit(:title, :description, :screenshots_attributes => [:image])
end
end
In views/projects/_forms.html.erb
<%= form_for @project, :html => {:multipart => true, :class => "form-horizontal project" } do |f| %>
<div class="form-group">
<%= f.label :title, :class => 'col-sm-2 control-label' %>
<div class="col-sm-10">
<%= f.text_field :title, :class => 'form-control' %>
</div>
<%= error_span(@project[:title]) %>
</div>
<div class="form-group">
<%= f.label :description, :class => 'col-sm-2 control-label' %>
<div class="col-sm-10">
<%= f.text_area :description, :class => 'form-control' %>
</div>
<%= error_span(@project[:description]) %>
</div>
<div class="form-group">
<%= f.fields_for :screenshots, @project.screenshots do |f_screenshot| %>
<%= f_screenshot.label :image, :class => 'col-sm-2 control-label' do %>
Screenshots
<% end %>
<div class="col-sm-10">
<%= f_screenshot.file_field :image, multiple: true, :name=>'project[screenshots_attributes][]
', :class => 'form-control' %>
</div>
<% end %>
</div>
<div class="form-actions">
<%= f.submit nil, :class => 'btn btn-primary' %>
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
projects_path, :class => 'btn btn-default' %>
</div>
<% end %>
Reference: Stackoverflow









