Fippiyのプログラム学習内容アウトプットBlog

日々の学習内容をアウトプットして振り返りを実施する。

Laravel開発、ユーザー情報を削除する

ユーザーの情報を扱うページを実装しています。登録・編集まで完了したので、最後にユーザー削除機能を実装していきます。

今回の目的

ユーザー情報と関連する書籍所有情報を削除する

なぜやるか

ユーザー情報を扱う一連の機能を全て作成し、あらゆる状況に対応するため

やりたいこと

ユーザーテーブルから対象ユーザーを削除する

ユーザー情報に紐付く関連情報も削除する

やったこと

削除に必要な情報とはなにか

ユーザー削除ページを作成する

ユーザーを削除する

ユーザー関連情報を削除する

ユーザー削除と同時に関連情報を削除する

実施内容

削除する情報を整理する

削除削除と言ってますが、何を削除するべきかを確認します。

Userテーブルに登録されているログイン中ユーザーの情報(名前・メール・パスワード)は残すべきではないので全て削除の対象とします。

後は、所有書籍情報内のログインユーザーが登録した情報です。Propertyテーブルに保存していますが、ユーザーが削除されるので所有情報も不要となります。

これらの情報が全て削除できれば、削除を希望するユーザーの全情報が削除できます。

 

ユーザー削除を実装する 

削除する為の導線を設置する

まずは、ルート・コントローラー・ビューを作成し、削除ボタンを設置する所までを実装します。

 

ルーティングの追加

# ~/routes/web.php

Route::get('/user/delete', 'UserController@delete');
Route::resource('user', 'UserController',['except' => ['show', 'edit']]);

削除ページを/user/deleteへ設置する為、ルートを新規作成しました。

削除実施アクションはdestoryとし、リソースから利用します。

 

コントローラー設定

 # ~/app/Http/Controllers/UserController.php

public function destroy($id)
{
return '<a href="/user/delete">もどる</a>';
}
 
public function delete()
{
$auth = Auth::user();
return view('user.delete',[ 'auth' => $auth ]);
}

deleteアクションでユーザー情報を取得し、確認画面を表示します。

destroyアクションでユーザーを削除します。が、一端画面遷移を確認するテキストとして作成しました。リンクをクリックすることで元のページに戻るようにしています。

 

ビューファイル作成

# ~/resources/views/user/delete.blade.php

<form action="{{ route('user.destroy', $auth->id)}}"
 method="post" enctype="multipart/form-data">
<div class="form-foot">
{{ csrf_field() }}
<input type="hidden" name="_method" value="DELETE">
<input class="send" type="submit" value="削除">
</div>
</form>

indexを流用し、削除ボタンを追加しました。

# ビュー表示

f:id:Fippiy:20190423121837p:plain

ユーザー削除画面

 

メニューのユーザー情報削除をクリックすることでdelete画面を表示させました。

ここで表示ユーザーが消去されることを確認し、削除ボタンを押すことでユーザーが消去される流れとします。

 

ユーザーを削除する 

まずは、ユーザー情報を単純に削除する手順から実装します。

 # ~/app/Http/Controllers/UserController.php

public function destroy($id)
{
// ユーザー削除
User::destroy($id);
return redirect('/');
}
 

フォームからユーザーidを取得して削除します。

削除完了後は、トップページに戻ります。

 

これだけでユーザー情報自体は削除可能になりました。

しかし、ユーザー所有書籍情報も一緒に削除する必要があるため、追加実装していきます。

# ~/app/Http/Controllers/UserController.php

public function destroy($id)
{
// 所有書籍削除
Property::where('user_id',$id)->delete();
// ユーザー削除
User::destroy($id);
return redirect('/');
}
 

 ユーザー所有書籍についても該当するものを全て削除する記述を追加しました。

 

以上でデータ消去は完了…としたいところですが、ユーザー消去時に関連情報も一緒に消せないか調べてみました。

今はテーブルが3つしかありませんが、もっと大がかりな物となると、全テーブルから削除する処理を書く…というのは現実的ではありません。

 

こちらを参考にさせて頂きました、ありがとうございます。

qiita.com

マイグレーションファイルで外部キー設定することで、ユーザー削除時に一緒に消すことができそうです。

外部キーを設定する

Propertiesテーブルの設定を変更します。

# ~/database/migrations/xxxx_create_properties_table.php

Schema::create('properties', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('user_id')->unsigned();
$table->integer('bookdata_id')->unsigned();
$table->integer('number');
$table->date('getdate')->nullable();
$table->text('freememo')->nullable();
$table->timestamps();

$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
});

これで、マイグレーションしてみるも、エラーとなりました。

   IlluminateDatabaseQueryException : SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: alter table `properties` add constraint `properties_user_id_foreign` foreign key (`user_id`) references `users` (`id`) on delete cascade)

 

エラー内容についてはこちらを参考にさせて頂きました、ありがとうございます。

qiita.com

外部キー設定するには型を完全一致にする必要がある模様。

 

上記サイトの他にこちらも参考にさせて頂きました、ありがとうございます。

qiita.com

Userテーブルのuser_idを登録しているintrger型が4バイトに対して、Propertyテーブルのidを登録しているincrementsとして指定しているbigint型は8バイトです。これにより不一致と判断されているようです。

さらにincrementsとして自動採番となっているUserテーブルのidはunsined属性が付与されて符号なしの状態、こちらも型が一致していない原因。

 

bigIncrementsに対応する外部キー設定をする

符号なしのincrementsが設定できればいい。

…というわけで、Userテーブルのidカラム型に対応する設定をPropertyテーブルのuser_idに設定します。

# ~/database/migrations/xxxx_create_properties_table.php

Schema::create('properties', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->integer('bookdata_id')->unsigned();
$table->integer('number');
$table->date('getdate')->nullable();
$table->text('freememo')->nullable();
$table->timestamps();

$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
});

これでマイグレーションファイルが正常に読み込まれました。

 

外部キー設定を利用してユーザー情報を全て削除する

関連情報が消えることを確認するために、propertyテーブル消去のコードを除外します。

# ~/app/Http/Controllers/UserController.php

public function destroy($id)
{
// 所有書籍削除
// Property::where('user_id',$id)->delete();
// ユーザー削除
User::destroy($id);
return redirect('/');
}

この状態でユーザーと所有書籍を登録した状態で削除が出来ました。

削除が確認できたので、除外したコードは不要となるため削除します。

# ~/app/Http/Controllers/UserController.php

public function destroy($id)
{
User::destroy($id);
return redirect('/');
}

結果として削除はidを指定して消すだけ…。あとはテーブルの設定で関連データまで一気に消えてくれました。

 

以上でユーザー情報編集の一連の動作を作成することができました。