2
4

More than 3 years have passed since last update.

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

Last updated at Posted at 2021-08-03

初めに

スクリーンショット 2021-08-03 22.38.52.png

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

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

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

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

ちなみにグループの削除機能は難しかったです。

(初心者には厳しい内容でした・・・。)

まずは編集から

コントローラー

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 %>

グループの削除機能

ただ、destoryするだけ!簡単!と思ってたのですが、

全然違いました。色々試してみても、消えない!エラーばっかり!

ルーティング作成

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

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

コントローラー記述

groups_controller.rb
 def all_destroy
    @group = Group.find(params[:group_id])
    if @group.destroy
    redirect_to groups_path
    end
  end
出してしまったエラー

まず、(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

Viewファイル

削除するボタン

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" %>```
まだまだ終わりません...:joy:

今のままだと、エラーが出ます...

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

スクリーンショット 2021-08-03 22.08.35.png

解決策; dependent: :destroy を付ける

group.rb
class Group < ApplicationRecord
  has_many :group_users
  # グループは複数のユーザーを持つ。group_usersから参照可能
  has_many :users, through: :group_users,dependent: :destroy
  # グループオーナー表示のために
  belongs_to :user
user.rb
 has_many:group_users
  # group_usersは中間テーブル
  has_many:groups, through: :group_users,dependent: :destroy
  # グループオーナー表示のため
  has_many :owned_groups, class_name: "Group"
これで削除できます!

何故、おとなしく消えてくれなかったのか...?

そもそもちゃんと最初から、dependent destroyはつけるべきだったなぁとも思いました。

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

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

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4