destroy_allとは?
すでにテーブルに存在するレコードを一括で削除するメソッドです。
テーブルの状態
usersテーブル(1)にtasksテーブル(多)がhas_manyで紐付いています。
user.rbはこのようになっています。
# == Schema Information # # Table name: users # # id :bigint not null, primary key # admin :boolean default(FALSE) # email :string(255) # image :string(255) # name :string(255) # password_digest :string(255) # remember_digest :string(255) # created_at :datetime not null # updated_at :datetime not null #
class User < ApplicationRecord has_many :tasks, dependent: :destroy accepts_nested_attributes_for :tasks, allow_destroy: true
1対多の場合は1の方(例としてuserとする)has_many :tasks, dependent: :destroyを追加記述することで、userを消したときに紐付いているtaskも削除されるようにできる!
sessions_helper.rbはこのようになっています(ほぼRailsチュートリアルと同じです)
module SessionsHelper # 記憶トークンcookieに対応するユーザーを返す def current_user if (user_id = session[:user_id]) @current_user ||= User.find_by(id: user_id) elsif (user_id = cookies.signed[:user_id]) user = User.find_by(id: user_id) if user && user.authenticated?(cookies[:remember_token]) log_in user @current_user = user end end end # 渡されたユーザーがログイン済みユーザーであればtrueを返す def current_user?(user) user == current_user end # 記憶したURL (もしくはデフォルト値) にリダイレクト(フレンドリーフォワーディング) def redirect_back_or(default) redirect_to(session[:forwarding_url] || default) session.delete(:forwarding_url) end end
task.rbはこのようになっています
# == Schema Information # # Table name: tasks # id :bigint not null, primary key # content :text(65535) # done :boolean # priority :integer # title :string(255) # created_at :datetime not null # updated_at :datetime not null # user_id :bigint # # Indexes # # index_tasks_on_user_id (user_id) # index_tasks_on_user_id_and_created_at (user_id,created_at) # # Foreign Keys # # fk_rails_... (user_id => users.id) #
class Task < ApplicationRecord belongs_to :user end
routes.rbに以下の記述を追加します。
resources :tasks do collection do delete 'destroy_all' end end
次にtasksコントローラーにdestroy_allアクションと
correct_user_destroy_allを定義します。
class TasksController < ApplicationController before_action :correct_user_destroy_all, only: :destroy_all # 一括削除 def destroy_all @tasks.destroy_all flash[:danger] = "全て削除しました!" #↓ここは自由でいいです redirect_to request.referrer || root_url end private #現在のユーザーが削除対象のtasksを保有しているかどうかを確認します。 def correct_user_destroy_all @tasks = current_user.tasks redirect_to root_url if @tasks.nil? end end
全て削除するボタンをビューに作成します。tasks/show.html.erbに以下の記述をします。
<%= button_to "全て削除", destroy_all_tasks_path, method: :delete %>
#フォントオーサムを使う場合 <%= link_to(content_tag(:i, '', class: "fas fa-bomb fa-3x ", style: "color: rgb(80,80,80);"), destroy_all_tasks_path, method: :delete, data: { confirm: "全て削除します。本当に削除しますか?" }) %>
destroy_allメソッドはモデルを介して削除を実行します。