-
Notifications
You must be signed in to change notification settings - Fork 1.7k
How to: Add more files and remove single file when using default multiple file uploads feature
Charles Jan edited this page Dec 12, 2023
·
4 revisions
You could use PostgreSQL array to implement such a feature. To be specific, in your migration, you could write
class AddImagesToGallery < ActiveRecord::Migration
def change
add_column :galleries, :images, :string, array: true, default: [] # add images column as array
end
end
In your view, you could do this
.field
= f.file_field :images, multiple: true # make this input a multiple files input
In your controller, you could allow nested params in the following way
def gallery_params
params.require(:gallery).permit(:title, {images: []}) # allow nested params as array
end
When you want to implement add more and remove single image feature, you could write your routes in the following way
Rails.application.routes.draw do
resources :galleries do
resources :images, :only => [:create, :destroy] # support #create and #destroy
end
end
So that you could implement your views in the following way
h1 Add more images
= form_for @gallery, url: gallery_images_path(@gallery), method: :post do |f| # use customized url endpoint
.field
= f.file_field :images, multiple: true
.actions = f.submit "Add More Images"
And
div
- @gallery.images.each_with_index do |image, index| #grab the index
div
= image_tag(image.url)
= link_to "Delete", gallery_image_path(@gallery, index), :method => :delete, data: { confirm: "Are you sure you want to delete this image?" }
So that you could implement your image controller in the following way
class ImagesController < ApplicationController
before_action :set_gallery
def create
add_more_images(images_params[:images])
flash[:error] = "Failed uploading images" unless @gallery.save
redirect_to :back
end
def destroy
remove_image_at_index(params[:id].to_i)
flash[:error] = "Failed deleting image" unless @gallery.save
redirect_to :back
end
private
def set_gallery
@gallery = Gallery.find(params[:gallery_id])
end
def add_more_images(new_images)
images = @gallery.images
# If you don't want to re-upload existing files, you should use
# `@gallery.images = images.map(&:identifier) + new_images`
# instead of the following statement
images += new_images
@gallery.images = images
end
def remove_image_at_index(index)
remain_images = @gallery.images
if index == 0 && @gallery.images.size == 1
@gallery.remove_images!
else
deleted_image = remain_images.delete_at(index)
deleted_image.try(:remove!)
# Also,you need to use `@gallery.images = remain_images.map(&:identifier)`
# to prevents re-uploading existing files
@gallery.images = remain_images
end
end
def images_params
params.require(:gallery).permit({images: []}) # allow nested params as array
end
end
For more detailed step by step walkthrough, please refer to Multiple Images Uploading With CarrierWave and PostgreSQL Array