作るもの
- お問い合わせフォーム
- REST(CRUD機能の作成)
作成の流れ
- Model → Controller → Route → View
Read & Create
-
Model
-
まずDBのテーブル及びカラム作成から行っていく
-
php artisan make:model Models/〇〇 (-mc)
-mcとつけることで、マイグレーションとコントローラーファイルも用意してくれる- 実際のマイグレーションファイルの記述は以下のようになる
public function up() { Schema::create('contact_forms', function (Blueprint $table) { $table->bigIncrements('id'); //氏名、メールアドレス、url、性別、年齢、お問い合わせ内容 //unsigned -> 符号(+,-)がない $table->string('your_name', 20); $table->string('email', 255); $table->longText('url')->nullable($value = true); $table->boolean('gender')->unsigned(); $table->tinyInteger('age'); $table->string('contact', 200); $table->timestamps(); }); }
-
php artisan migrate
これを行うことで、マイグレーションファイルが起動し、実際にDBにテーブルが作成される。 - Schema::create関数は、引数1に作成するテーブル名、引数2にカラムの作成手順を指定している
- unsignedは、+,-の符号のうち、-を認めない機能。RDBで繋げるときに、この設定が違い違いになっていたらエラーが出るので、明示しておく。
-
-
Controller
- RESTfulなコントローラーを作成する
-
php artisan make:controller 〇〇 —resource
と入力することで、CRUD機能の土台を既に持っている、〇〇というControllerを作成することができる
-
View
- リンク先にはRouteと同じ書き方が使える
- laravelのformには@csrfが必須
<form method="GET" action="{{ route('contact.create') }}"> @csrf <button type="submit" class="btn btn-primary"> 新規登録 </button> </form>
-
Route
- prefixは共通のフォルダ名、middlewareはAuth::routes();の認証機能を読み込んでる。
Auth::routes(); Route::group(['prefix' => 'contact', 'middleware' => 'auth'], function () { Route::get('index', 'ContactFormController@index')->name('contact.index'); Route::get('create', 'ContactFormController@create')->name('contact.create'); });
DBに投稿内容を保存
- storeで書いていく
DBの投稿内容を表示
投稿の詳細
Route
Route::get('show/{id}', 'ContactFormController@show')
->name('contact.show');
-
'show/{id}'
と書くことで、各投稿に紐づけられたIDを参照し、その詳細な投稿内容を引っ張り出してくることが可能
Controller
public function show($id)
{
$contact = ContactForm::find($id);
if($contact->gender === 0){
$gender = '男性';
}
if ($contact->age === 1) {
$age = '10代';
}
return view('contact.show', compact('contact','gender','age'));
}
- findは一つのデータを持ってくるイメージ
- だから変数名も単数系
- returnで渡しているデータ(compact)は、書き方の特徴として[$]が不要
- それに複数の値を渡すことができる
- DBでint他で管理しているものは、そのcontroller内で加工処理をしてあげる
- 今回はintで管理しているものに、新しい変数を設定して、それをcompactでまとめてViewに送っている
View
{{ $contact->your_name}}
{{ $gender}}
{{ $age}}
- Viewで表示するときは[$]が必要
別のViewから飛んでくる
<td><a href=
"{{route('contact.show', ['id' => $contact->id])}}">
詳細を見る</a>
- ルートでパラメータを定義している場合は、route関数の第2引数としてパラメータを渡す。指定されたパラメータは自動的にURLの正しい場所へ埋め込まれる
- 今回であれば、contact.showというrouteで定義した名前だけではなく、パラメータのidも定義してあげている
- $contact→idはもちろんこのビューにもcontrollerからデータを飛ばしていることが前提にある
- 今回であれば、contact.showというrouteで定義した名前だけではなく、パラメータのidも定義してあげている
Edit画面
Route
Route::get('edit/{id}', 'ContactFormController@edit')->
name('contact.edit');
- showで投稿の詳細画面を作成したが、イメージとしてはそれと同じ。
- 各投稿の詳細を持ってくるためにパラメーターにidを指定して、その投稿を表示させる
Controller
public function edit($id)
{
//
$contact = ContactForm::find($id);
return view('contact.edit', compact('contact'));
}
- DBから投稿データを(idを基に)引っ張ってきて、Viewに投稿データを渡している
View
//createとほぼ同じ
//変更点は、各入力欄に初期値として投稿データを渡している
<input type="text" name="title" value="{{$contact->title}}">
//gender,ageのように数値で管理しているものの記述は少し違う
<input type="radio" name="gender" value="0"
@if($contact->gender === 0 ) checked @endif >
男性
</input>
<input type="radio" name="gender" value="1"
@if($contact->gender === 1 ) checked @endif>
女性
</input>
- もちろんformで囲っているので、こっからDBに登録されているデータを更新する処理を書いていく必要がある
- intで管理しているチェックボックス系は、引っ張ってきたデータがその数値と一致していたら、checked(selected)にする、というif文で対応する
Update
Route
Route::post('update/{id}', 'ContactFormController@update')
->name('contact.update');
Controller
public function update(Request $request, $id)
{
//
$contact = ContactForm::find($id);
$contact->your_name = $request->input('your_name');
$contact->title = $request->input('title');
$contact->email = $request->input('email');
$contact->url = $request->input('url');
$contact->gender = $request->input('gender');
$contact->age = $request->input('age');
$contact->contact = $request->input('contact');
$contact->save();
return redirect('contact/index');
}
- データの登録という面ではstoreと同じなので、型はstoreを流用
- storeと違う部分
- 現在のデータを持ってくる(新しくインスタンスを作成することはしない)
View
Editです!
<form method="POST"
action="{{route('contact.update', ['id' => $contact->id])}}">
- action先にcontrollerのupdateメソッドを指定している
- 各投稿の情報を基にデータの更新作業をしているので、idの指定は忘れない
Destroy
Route
Route::post('destroy/{id}', 'ContactFormController@destroy')
->name('contact.destroy');
- その投稿を削除するので、show,editと同じ
Controller
public function destroy($id)
{
$contact = ContactForm::find($id);
$contact->delete();
return redirect('contact/index');
}
- データを一つ引っ張ってきて、deleteするだけ
View
<form method="POST" action="{{route('contact.destroy', ['id' => $contact->id])}}" id="delete_{{$contact->id}}">
@csrf
<a href="#" class="btn btn-danger" data-id="{{$contact->id}}" onclick="deletePost(this);" type="submit">削除する</a>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
function deletePost(e){
'use strict';
if (confirm('本当に削除していいですか?')){
document.getElementById('delete_' + e.dataset.id).submit();
}
}
</script>
@endsection
- show.bladeのなかにformを二つ作っている
- ごちゃごちゃしているのは、削除ボタンを押したときに「本当に削除しますか?」という表示を挟んでいるから