Laravelの使い方（CRUD処理について）

## Laravelを使用したCRUD処理のやり方

# Create機能について
①viewの部分を作成する。
　resources/viewsにphpファイルを追加する。
　メモ：フォームを作成した場合、以下のように書くとXSS対策ができる。
```html
<form action="#" method="post">
@csrf    <!-- これ -->
</form>
```
②フォームを表示するためのコントローラ（①を表示する）を作成する。
③フォームに入力した内容を保存するためのコントローラを作成する。

1.モデルをインスタンス化して新しいレコードを作成する。
```〇〇Controller.php
public function 任意のメソッド名(Request $request) {
    $任意のインスタンス名 = new モデルクラス名();  // これ
}
```
・任意のメソッド名(Request ＄request)：このような書き方をするとRequestクラスが使用できる。
・＄任意のインスタンス名 = new モデルクラス名();：
　モデルクラスのインスタンスを生成して、新しいレコードを作成する。

2.フォームから送信された入力内容を各カラムに代入する。
```〇〇Controller.php
public function 任意のメソッド名(Request $request) {
    $任意のインスタンス名 = new モデルクラス名();
    $任意のインスタンス名->カラム名 = $request->input('カラム名');  // これ
}
```
・$request->input('カラム名');：フォームに入力された値を取得する。
・id、created_at、updated_atカラムには自動で値が挿入されるため、コードを書く必要はない。

3.テーブルにデータを保存する。
```〇〇Controller.php
public function 任意のメソッド名(Request $request) {
    $任意のインスタンス名 = new モデルクラス名();
    $任意のインスタンス名->カラム名 = $request->input('カラム名');
    $任意のインスタンス名->save();  // これ
}
```
# Read機能について
①ControllerとModel間でやり取りをして、データベースの値を取得する。
　**※処理はControllerに記述する。**
　例：topページを表示した時にデータベースの値も表示する場合
```〇〇Controller.php
class 〇〇Controller extends Controller {
    // 一覧ページ
    public function index() {        
        // テーブルの全データを新しい順で取得する。
        $posts = Modelクラス名::latest()->get();
        // 変数postsをindex.blade.phpに渡す。
        return view('posts.index', compact('posts'));
}
```

```PHP
// テーブルの全データを取得する
$table = モデルクラス名::all();

// postsテーブルの全データを新しい順で取得する
$table = モデルクラス名::latest()->get();
```
※all()メソッドやget()メソッドは、collectionというクラスのインスタンスを戻り値として返す。
　collectionクラスは簡単にいえば配列をより使いやすくしたクラス。
　配列と同様にforeach文で中身を順番に取り出すことが可能。

```PHP
// 変数$tableをルート名/index.blade.phpに渡す
return view('posts.index(名前付きルートを記述)', compact('table'));
```
※compact()関数＝引数に渡された変数とその値から配列を作成し、戻り値として返す関数。
　（引数に変数名を指定する時、"$"は不要。）

②viewに①で取得したテーブルの値を表示する。
```index.blade.php
@foreach($テーブルが入った変数名 as $任意の変数名)
    <div>
        <div>
            <h2>{{ $任意の変数名->カラム名 }}</h2>
            <p>{{ $任意の変数名->カラム名 }}</p>     
        </div>
    </div>
@endforeach  
```
・Controllerからテーブルを渡された時、配列のような形式になっているので、for文で出力可能。
※$テーブルが入った変数名：Controllerから渡された変数名を記述する。

### メモ：各投稿の詳細ページを作成する場合
①詳細ページ用のルーティングを設定する。
```〇〇Controller.php
Route::get('/posts/{モデル名}', [PostController::class, 'show'])->name('posts.show');
```
※URLの{モデル名}にidが入る。
　URLはモデル名(小文字、単数形)を{}で囲む → モデルのインスタンスが受け取れるようになり、自動で{モデル名}idが入る。

②viewにルートを呼び出す記述をする。
```index.blade.php
@foreach($posts as $post)
    <a href="{{ route('名前付きルート', $post) }}">詳細</a>
@endforeach
```
※routeヘルパーの第二引数はforeachの$postを記述する。
　→postモデルのインスタンスを渡している。

②コントローラのアクションを作成する。
```〇〇Controller.php
     public function 任意の関数名(モデル名 $post) {
         return view('名前付きルート', compact('任意の関数名の引数'));
     }
```
**※任意の関数名の引数名は、ルーティングのURLの波括弧{}で囲まれた文字列と一致させる必要がある。**

### route()ヘルパーで複数のモデルのインスタンスをコントローラに渡す書き方
```○○.blade.php
route('goals.todos.update', [$goal, $todo])
```
第二引数に配列の形でモデルを記述する。

### インスタンス化せずにモデルを使用する方法
Authファサードを使用する。
（ファサード：クラスをインスタンス化せずに使用できるLaravelの機能のこと。）

①テーブルのリレーションシップを設定する。
設定方法は以下を参照。
https://qiita.com/miki_grapes/items/3e1d5e347d1bb8be375d#1%E5%AF%BE%E5%A4%9A%E3%81%AE%E3%83%AA%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%B7%E3%83%83%E3%83%97%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B

②Use宣言を書く。
```○○Controller.php
use Illuminate\Support\Facades\Auth;
```
③モデルクラスを使用したいメソッド内に以下のように記述する。
```○○Controller.php
$任意の変数名 = Auth::モデルクラス名()->リレーションシップを設定したメソッド名;
```
```OrderDetailController.php
// ↓例：1対多の関係で、userテーブルとorderDetailテーブルがある場合
$orderDetail = Auth::user()->orderDetails;
```
↑特定のユーザーのorderDetailをすべて取得できる。
**リレーションシップを設定しないとこのような書き方ができない。**



## Update機能のついて
①更新用のルーティングを設定する。
```web.php
// 更新ページ
Route::get('/posts/{モデル名}/edit', [PostController::class, 'edit'])->name('posts.edit(任意の名前)');
 
 // 更新機能
Route::patch('/posts/{モデル名}', [PostController::class, 'update'])->name('posts.update(任意の名前)');
```
※更新する時のHTTPリクエストメソッドは、PATCHとPUTどっちでも良い。
　・PUT：全体的な更新
　・PATCH：部分的な更新

②viewに更新ページのルートを呼び出す記述をする。
```index.blade.php
@foreach($posts as $post)
    <a href="{{ route('名前付きルート', $post) }}">編集</a>
@endforeach
```

③コントローラにアクションを追加する。
```〇〇Controller.php
// 編集ページ
public function 任意の関数名(モデル名 $post) {
	return view('名前付きルート', compact('任意の関数名の引数'));
}

// 更新機能
public function update(Request $request, Post $post) {
    $post->title = $request->input('title');    // フォームに入力された値を代入する
    $post->save();

    return redirect()->route('posts.show', $post)->with('任意の名前','投稿を編集しました。');	
}
```
※更新機能の注意点：
・$postを変更するため、モデルのインスタンス化はしなくて良い。
・returnは詳細ページに戻る動作のため、routeヘルパーの第二引数にモデルのインスタンスを設定している。

④viewにフラッシュメッセージを表示する記述をする。
```〇〇.blade.php
@if (session('任意の名前'))
    <p>{{ session('任意の名前') }}</p>
@endif
```
⑤更新用のviewを作成する。
```〇〇.blade.php
<form action="{{ route('posts.update', $post) }}" method="post">
    @csrf
	@method('patch')
	<div>
		<label for="title">タイトル</label>
		<input type="text" name="title" value="{{ $post->'title' }}">
	</div>
	<div>
		<label for="content">本文</label>
		<textarea name="content" value="{{ $post->'content' }}"></textarea>
	</div>
	<button type="submit">更新</button>
</form>
```
※formのアクション属性には更新用のルーティングとモデルのインスタンスを渡す。
　（特定の投稿を更新したいため、idが必要。）
※@method('patch')：更新機能のルーティングに設定したHTTPリクエストメソッドが、getとpost以外の場合は記述する。(HTMLのフォームはgetとpostしか対応していないため。)

## Delete機能について
①削除用のルーティングを設定する。
```web.php
Route::delete('/posts/{モデル名}', [PostController::class, '任意の名前'])->name('任意の名前');
```
※特定の投稿を削除するためにidが必要なので、URLの後に{モデル名}が必要。

②viewに削除ボタンを追加する。
```index.blade.php
<form action="{{ route('posts.destroy', $post) }}" method="post">
    @csrf
    @method('delete')                                        
    <button type="submit">削除</button>
</form>
```
・削除機能のルーティングのHTTPリクエストメソッドは"DELETE"のため、form内に@method('delete')と記述する。
　→詳細や編集ボタンのようなaタグではなく、formタグを記述する。（aタグは自動的にGETになってしまう。）

③コントローラのアクションを作成する。
```〇〇Controller.php
public function 任意の関数名(モデル名 $post) {
    $post->delete();

    return redirect()->route('index.blade.phpの名前付きルート')->with('任意の名前', '投稿を削除しました。');
}
```
↑特定の投稿を削除して、topページに戻り、topページにフラッシュメッセージを表示している。