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