Ruby 2.5.1 Rails 5.2.4.3
I want to implement a function that can post / delete multiple images using Rails standard file management function Active Storage.
$ rails new sample_app
$ cd sample_app 
$ bin/rails db:create
At another terminal
$ bin/rails s
If you access http: // localhost: 3000 and see a familiar image, it's OK.
 
This time with the name post.
$ bin/rails g model post name:string 
$ bin/rails db:migrate
$ bin/rails g controller posts
config/routes.rb
Rails.application.routes.draw do
  resources :posts
end
$ bin/rails active_storage:install
Copied migration 20200726095142_create_active_storage_tables.active_storage.rb from active_storage
A migration file is created that creates the following two tables. ・ Active_storage_attachments ・ Active_storage_blobs Migrate to create a table.
$ bin/rails db:migrate
== 20200726095142 CreateActiveStorageTables: migrating ========================
-- create_table(:active_storage_blobs)
   -> 0.0020s
-- create_table(:active_storage_attachments)
   -> 0.0019s
== 20200726095142 CreateActiveStorageTables: migrated (0.0041s) ===============
Make it available in association with the model
models/posts.rb
class Post < ApplicationRecord
  has_many_attached :images
end
controllers/posts_controller.rb
class PostsController < ApplicationController
  def index
    @posts = Post.all
  end
  def new
    @post = Post.new
  end
  def create
    @post = Post.new(post_params)
    if @post.save
      flash[:success] = "created"
      redirect_to posts_path
    else
      render :new
    end
  end
  def destroy
    @post = Post.find(params[:id])
    @post.destroy
    flash[:success] = "created"
    redirect_to posts_path
  end
  private
  def post_params
    params.require(:post).permit(:name, images: [])
  end
end
Post list page
erb:posts/index.html.erb
<h1>Post list</h1>
<%= link_to 'New post', new_post_path %>
<%= render @posts %>
This time, create a partial post and display it.
erb:posts/_post.html.erb
<div class="post-partial">
  <li id="post-<%= post.id %>">
    <%= post.name %>
    <% post.images.each do |image| %>
      <%= image_tag(image, width:100) %>
    <% end %>
    <%= link_to 'Delete', post, method: :delete, data: { confirm: 'Deleteしてよろしいですか?' } %>
  </li>
</div>
Multiple: true is required when posting multiple images
erb:posts/new.html.erb
<%= form_with(model: @post, local: true) do |f| %>
  <div>
    <%= f.label :name, 'name' %>
    <%= f.text_field :title %>
  </div>
  <div>
    <%= f.label :images, 'image' %>
    <%= f.file_field :images, multiple: true %>
  </div>
  <div>
    <%= f.submit  'Post' %>
  </div>
<% end %>
I was able to post multiple images from a new post.
 
Add the edit and update methods required for editing.
controllers/posts_controllers.rb
  def edit
    @post = Post.find(params[:id])
  end
  def update
    post = Post.find(params[:id])
    if params[:post][:image_ids]
      params[:post][:image_ids].each do |image_id|
        image = post.images.find(image_id)
        image.purge
      end
    end
    if post.update_attributes(post_params)
      flash[:success] = "Edited"
      redirect_to posts_url
    else
      render :edit
    end
  end
It is almost the same as the new post page, but the part to display the registered image and check it is added.
erb:posts/edit.html.erb
<%= form_with(model: @post, local: true) do |f| %>
  <div>
    <%= f.label :name, 'name' %>
    <%= f.text_field :name %>
  </div>
  <div>
    <%= f.label :images, 'image' %>
    <%= f.file_field :images, multiple: true %>
  </div>
  <% if @post.images.present? %>
    <p>Currently registered images (check what you want to delete)</p>
    <% @post.images.each do |image| %>
      <%= f.check_box :image_ids, {multiple: true}, image.id, false %>
      <%= image_tag image, size:"100x100" %> <br>
    <% end %>
  <% end %>
  <div>
    <%= f.submit  'To edit' %>
  </div>
<% end %>
erb:posts/index.html.erb
<div class="post-partial">
  <li id="post-<%= post.id %>">
    <%= post.name %>
    <% post.images.each do |image| %>
      <%= image_tag(image, width:100) %>
    <% end %>
    <%= link_to 'Edit', edit_post_path(post.id) %>  #add to
    <%= link_to 'Delete', post, method: :delete, data: { confirm: 'Deleteしてよろしいですか?' } %>
  </li>
</div>
Click the edit link from your browser and check only the images you want to delete.

I was able to delete only any image.
 
Try managing multiple images using Active Storage How to delete multiple images with ActiveStorage
Recommended Posts