初めに
①②の記事でグループの作成、グループへの参加、退会機能を実装しました。
③ではグループ管理者の表示も行いました。
しかし、グループの編集/削除機能をすっかり忘れていましたので、今回グループの編集機能をつけていきます。
注意①②と③④で作ってるアプリが違います。
①②は本の投稿(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' #ここ!
省略
コントローラー記述
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になってるからです。
Viewファイル
削除するボタン
<% 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" %>```
まだまだ終わりません...
今のままだと、エラーが出ます...
多分、これが出ると思います!!
解決策; dependent: :destroy を付ける
class Group < ApplicationRecord
has_many :group_users
# グループは複数のユーザーを持つ。group_usersから参照可能
has_many :users, through: :group_users,dependent: :destroy
# グループオーナー表示のために
belongs_to :user
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のキーを持ってるってことになってしまうと。
参照できないキーを持つことになってしまう..と。
(頭いいなぁ。。そんなことまで考えてるのかと思いました。)
なので、グループが消えた際には、外部キーとして設定してるレコードにも、
消えてもらう必要があります