仮に(チェット)ルームの削除機能を実装するために、
1.resources :roomsにdestroyアクションのルーティングを追記
Rails.application.routes.draw do
# 中略
resources :rooms, only: [:new, :create, :destroy] do
resources :messages, only: [:index, :create]
#メッセージはコメントです。親子関係(ネスト)です
end
end
2.roomsコントローラーにdestroyアクションを定義
1.チャットルーム削除対象の選定
Room.find(params[:id])を使用して、削除したいチャットルームの情報を取得します。
root(roomsのindex)にリダイレクトする記述をします。
destroyアクションは、削除するだけなのでビューの表示は必要はありません。
重要
他のindex,createなどのアクションもそうですが、何も記述しないと
###controllerでしてしてある同じ「def」より後ろに記述のあるアクションのアクションページに止まります。
class RoomsController < ApplicationController
# 中略
def destroy
room = Room.find(params[:id])
room.destroy
redirect_to root_path
end
# 中略
3.destroyアクション動かすlink_toを設定しましょう
"チャットを終了する"をクリックすると、チャットルームが削除されるようにリンクを設定します。
<div class="chat-header">
<div class="left-header">
<div class="header-title">
<%= @room.name%>
</div>
</div>
<div class="right-header">
<div class="header-button">
<%= link_to "チャットを終了する", room_path(@room), method: :delete %>
</div>
</div>
</div>
「rails routes」コマンドを実行すると、roomsコントローラーのdestroyアクションに対応するPrefixは、roomということが分かります。したがって、削除のパスはroom_pathとなります。
削除するチャットルームを区別するために、定義している@roomを引数にし、room_path(@room)と指定しましょう。
HTTPメソッドのdeleteを指定すると、roomsコントローラーのdestroyアクションが実行されます。
destroyアクションが実行されると、roomを削除することができます。
4.最後に、roomを削除したときに、そのroomに関連する情報も削除されるように設定
class Room < ApplicationRecord
has_many :room_users, dependent: :destroy
has_many :users, through: :room_users
has_many :messages, dependent: :destroy
validates :name, presence: true
end
アソシエーションオプション | 働き |
---|---|
dependent | 2つのモデルの間につながりがあることを明示的にRailsに対して宣言でき、それによってモデルの操作を一貫させることができます。dependentオプションに:destroyを指定した場合、Room(親モデル)が削除されたときに、関連付けしているMessageを削除できます。 |
MessageモデルとRoomUserモデルにdependent: :destroyを記述します。
dependentオプションに:destroyを指定した場合、Room(親モデル)が削除されたときに、関連付けしているMessage(子モデル)とRoomUser(子モデル)も削除されます。
参考:1 関連付けを使う理由「Railsガイド」
https://railsguides.jp/association_basics.html