[Ruby on rails]グループ作成機能④ グループ管理者のグループ編集/グループ削除 外部キー制約のデータ削除

<h2>初めに</h2>

![スクリーンショット 2021-08-03 22.38.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/993e7291-1dbf-3631-afbb-96aa91cab457.png)


①②の記事でグループの作成、グループへの参加、退会機能を実装しました。
③ではグループ管理者の表示も行いました。

しかし、グループの編集/削除機能をすっかり忘れていましたので、今回グループの編集機能をつけていきます。

:sunny:注意①②と③④で作ってるアプリが違います。
①②は本の投稿(bookモデル）サイトでの、グループ作成機能。
③④は記事の投稿（postモデル）サイトでの、グループ作成機能です。
①②と③④でGroupのカラムが若干違います。
グループ名（name)、
グループ紹介（introduction)
オーナーid(owner_id)は共通ですが、
①②では、t.string :image_idがあるのに対し、
③④では、image_idが無く、t.string :status（参加条件）を
付け足しています。

行う作業自体は変わりませんが、少しややこしいかもしれません...




<h6>ちなみにグループの削除機能は難しかったです。</h6>
（初心者には厳しい内容でした・・・。）

<h2>まずは編集から</h2>

コントローラー

```
def edit
    @group=Group.find(params[:id])
  end

  def update
    @group=Group.find(params[:id])
    if @group.update(group_params)
      redirect_to groups_path
    else
      render"edit"
    end
  end
```

viewページ

```
<%= form_with model: @group, local: true do |f| %>
    <div class="form-group">
      <%=f.label"勉強会名"%>
      <%= f.text_field:name,class:"form-control" %>
    </div>
    
    <div class="form-group">
      <%=f.label"紹介文"%>
      <%= f.text_area:introduction,class:"form-control"%>
    </div>
    
    <div class="from-group">
      <%=f.label"参加条件"%>
      <%= f.text_field:status,class:"form-control"%>
    </div>
    
    <div class="action" style="margin:20px 0;">
      <%=f.submit"変更を保存",class:"btn btn-light btn-block"%>
    </div>
 <% end %>
```

<h2>グループの削除機能</h2>

<h6>ただ、destoryするだけ！簡単！と思ってたのですが、</h6>
全然違いました。色々試してみても、消えない！エラーばっかり！

<h2>ルーティング作成</h2>
```resources :groups```で作成されるdestroyのルーティングは、
グループ退会で使っているので、新しく作ります。

```
resources :groups do
  get "join" => "groups#join"
   delete "all_destroy" => 'groups#all_destroy'　　　#ここ！
省略
```

<h2>コントローラー記述</h2>

```perl:groups_controller.rb
 def all_destroy
    @group = Group.find(params[:group_id])
    if @group.destroy
    redirect_to groups_path
    end
  end
```

<h6>出してしまったエラー</h6>
まず、(params[:group_id])です。
ここをeditみたいに、params[:id]で書くと、
```ActiveRecord::RecordNotFound in GroupsController#all_destroy
Couldn't find Group without an ID```というエラーが出ます。

ルーティング見るとわかるのですが、
editのルーティングは、groups/:id/editで、
all_destroyは、groups/:group_id/all_destroyになってるからです。

![スクリーンショット 2021-08-03 21.54.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/92244111-544f-bd8d-3641-cccd0531af37.png)

<h2>Viewファイル</h2>

削除するボタン

```perl:groups/show.html.erb
<% if @group.owner_id == current_user.id %>
 <%= link_to '勉強会削除',group_all_destroy_path(@group),
method: :delete,data: { confirm: '本当に削除しますか？' } ,
class: "btn btn-sm btn-outline-danger" %>```
```

<h6>まだまだ終わりません...:joy:</h6>
今のままだと、エラーが出ます...

多分、これが出ると思います！！

![スクリーンショット 2021-08-03 22.08.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/9099e7c5-0e23-055b-38bb-b56252745579.png)

<h2>解決策； dependent: :destroy を付ける</h2>

```perl:group.rb
class Group < ApplicationRecord
  has_many :group_users
  # グループは複数のユーザーを持つ。group_usersから参照可能
  has_many :users, through: :group_users,dependent: :destroy
  # グループオーナー表示のために
  belongs_to :user
```

```perl:user.rb
 has_many:group_users
  # group_usersは中間テーブル
  has_many:groups, through: :group_users,dependent: :destroy
  # グループオーナー表示のため
  has_many :owned_groups, class_name: "Group"
```

<h6>これで削除できます！</h6>

<h2>何故、おとなしく消えてくれなかったのか...?</h2>
そもそもちゃんと最初から、dependent destroyはつけるべきだったなぁとも思いました。

dependent: :destroyって、
「お前が消えたら、俺も消える！」みたいなやつだと思うのですが、
dependent: :destroyしてあげないと、仮にグループ１が消えたときに、
中間テーブル（仲介役）は、それを知らずにずっとグループ１のキーを持ってるってことになってしまうと。
参照できないキーを持つことになってしまう..と。
（頭いいなぁ。。そんなことまで考えてるのかと思いました。）
なので、グループが消えた際には、外部キーとして設定してるレコードにも、
消えてもらう必要があります:smiling_imp:


<h2>この記事のおかげでエラーから抜け出しました</h2>

https://note.com/ruquia7/n/ne20b0c667c60