やってみたLaravelチュートリアル③

# はじめに 🐢
[Laravelの教科書](https://amzn.asia/d/1xFOXD5)という本を見かけたので、
勉強のために、チュートリアルとして頭からやってみました。
その個人的な記録です。

本は 350ページ、12章 ありますが、内容的に
2～10章が手を動かしてやる系ぽいです。

環境構築の第２章、仕組みの第３，４章は済ませました。

- [やってみたLaravelチュートリアル①](https://qiita.com/tmatsumor/items/2cc8f9ac49a6fa28ad37)

- [やってみたLaravelチュートリアル②](https://qiita.com/tmatsumor/items/d2f1495ad1e2e8c099a1)

次の第５章、第６章に進みます。

:::note info
本が手元にあることが前提となっています
:::

# Ⅴ．データベース
第５章では、Laravel との DB連携について解説してあります。
一つずつ見ていきます。

## １．DBの設定
プロジェクトごとのDB設定は config/database.php にあります。
また、.env から接続設定を取ってきているので、これも確認しておきます。

## ２．モデルを使ったデータ取得
教科書では users テーブルを対象に TestController.php コントローラと
test ビューを利用してデータ取得を行う例が示されていました。
### TestController.php
Userモデルファイルを使用します。use宣言で読み込みます。
User::all() にて全読み込みしています。

::: note info
User モデルファイルは作った記憶が無いですが、
これは Laravel プロジェクト作成時に自動作成されるようです。
:::
compact 関数でモデルからの all をキーバリューペアにして
連想配列にして view に渡しています。
view の第二引数で、連想配列が渡せるようです。
### test ビュー
上記で作成した users 連想配列を foreach で回して name を表示します。
http://localhost/test にアクセスすると、以下が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508336/21c8cd14-66c4-5ade-011c-19356c59f343.png)
DB に ある users テーブルから name 列を取得して表示できました。

## ３．マイグレーションとモデル作成
教科書では、マイグレーションファイルを用いたテーブル作成の
解説があります。

::: note info
マイグレーションは移行って意味です。
:::

マイグレーションファイルを作成後、編集して
migrate コマンドの実行にて、DBに反映させます。

マイグレーションファイルはモデルのファイルとセットで作れるので、
通常は make:model モデル名 -m で作るのが良いでしょう。

::: note info
-m は --migration の短縮形のオプションです。
:::
### マイグレーションファイル
database/migrations 内に作成されます。
教科書に従い、Test モデルでマイグレーションファイルを作ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508336/cfdfa838-0503-f674-c228-fe64f4c5e092.png)
これを好きに編集して、テーブル定義を行えばよいわけですね。

::: note info
モデル名は Test、テーブル名は自動的に複数形の tests になってます。
:::
### マイグレート
第２章でも行いました、マイグレートです。
コマンドを実行し、マイグレーションファイルの内容を DB に反映させます。

### テーブル構造の変更
テーブル構造の変更：列追加や削除についても、
マイグレーションファイルを通します。

make:migration にて、ファイル名と対象テーブルを指定し、
マイグレーションファイルを発行します。

あとは、元のテーブルからの変更分をファイルに書き込んで保存し、
migrate コマンドを実行して DB に反映させます。

::: note info
ファイル内の down メソッド内の書き漏れに注意するように
記載がありました。ロールバック時の処理を忘れずに。
:::
# Ⅵ．フォームの作成と投稿
いよいよ、実践です。わくわく。
投稿用フォームを作ります。表示はそのあと。まずは登録。
## １．モデルとテーブルの作成
まずはデータの保管場所と、それに繋ぐモデルを。
投稿内容を保管するので Post モデルと posts テーブルを作ります。

make:model Post -m でマイグレーションファイルを発行、
ファイルを編集して title と body 列を追加します。

最後に、migrate を実行し DB に反映させます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508336/5c18b1f9-0106-85e2-7ed2-c6d6e9b0b5bd.png)
phpMyAdmin にて posts テーブルが作られていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508336/8bfbd91a-8272-cd69-a93e-6a64cfa4f600.png)
## ２．ビューの作成
教科書にて、views の中に post フォルダを作って、
中に create.blade.php を作るよう指示があります。
中身は dashboard.blade.php と共通する部分が多いとの事なので、
私はそれをコピーして、post の中に配置しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508336/b268f21f-aef5-118c-753e-f097a06ccd10.png)
dashboard.blade.php を create.blade.php にリネームし、
ファイルの内容を、教科書に従い変更しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508336/08535653-0681-8fd4-b31a-20c3766f09cd.png)
## ３．コントローラ
MVC+R なので、C：コントローラも必要です。
教科書に従い make:controller で PostController を作ります。

app/Http/Controllers/PostController.php が作られるので、
そのファイルを編集し、create メソッドを実装します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508336/cb552b44-42b8-26a3-adf1-4526b43dd698.png)

:::note info
create メソッドは、この後のルートで参照されます。
また create メソッド内の post.create の post. はディレクトリ。
:::
## ４．ルートの設定
routes/web.php にて PostController の
use 宣言と、Route.get を追記します。

:::note info
以前の TestController の記述のコピー編集で大丈夫です。
->name は除去。
:::
これにより、ルートが設定され、
PostController が呼び出され、ビューが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508336/d79f4e19-8ba4-25f5-fbce-b77dcf72d445.png)

:::note warn
ログイン済みでないと例外が出て適切に表示されませんでした。
（Attempt to read property "name" on null）
:::
## ５．データの保存
フォームが表示できるようになったので、
次は実際にデータを登録できるように改修します。

### モデルに設定を追加
まずは、値を保存・更新したいカラムに対し fillable を指定します。
Models の Post.php にて、設定を行います。
セキュリティ上の理由により記述が必要で、教科書に解説があります。

こちらにも詳しい解説があります。
[【Laravel】fillableはなぜ必要かを具体的に。](https://qiita.com/monji586/items/58d91891caa51b514166)

教科書に従い、Post クラスのプロパティに fillable 配列を追加します。

### ルートの追加
教科書に従い web.php にて store メソッドへのルート設定を行います。

::: note info
->name('post.store') は後ほど action  にて参照します。
:::
### ビューへの追記
次は、フォームからコントローラに値を渡せるように、
create.blade.php の修正を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508336/b5fce6ba-a426-c602-c081-b3b8b7d43964.png)

［送信する］ボタン押下時に post リクエストするので、
その親の form タブに、method と action を追加します。

action 内の route関数には post.store を引数で渡します。
これは先に［ルートの追加］で指定した 名前付きのルート設定です。

::: note warn
form タグ内には セキュリティ上の理由により
@csrf の追加が必要です。
:::

### コントローラへの store メソッドの追加
教科書に従い、PostController.php に store メソッドを追加します。
Post::create の引数では、フォーム内の title と body を
配列に入れて渡しています。

:::note info
return back() では、元のページに戻るように指示しています。
:::
ソースコードを保存したら、ブラウザからアクセスしてみます。
フォームを埋めて［送信する］ボタンを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508336/46b157c7-ad07-44fa-0ee8-cf24b8d4c63c.png)

画面上は変化がありませんが（内容はクリアされてしまいます）
以下のようにDBに入力内容が登録されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508336/45795d11-6d82-f081-af63-a0b0423657f0.png)

## ６．保存完了後のメッセージ表示

保存完了時に画面上に変化がないので（内容はクリアされる）
保存完了後はテキストメッセージを表示します。

store メソッドの中で、リクエストのセッション変数に
message「保存しました」という内容を保存します。

:::note info
Post::create が正常に処理された後に、
上記のセッション変数への保存が実行されます。
:::

この保存された値を、ビュー側で参照します。
form タグの上に @if(session('message')) を挿入し、
セッション変数 message が存在する場合は、
その値「保存しました」を表示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508336/db4e275d-ce44-9cc7-2297-1f2c4beb0bd3.png)
適切に表示されました。

## ７．バリデーション
フォームにバリデーション（入力値チェック）を追加します。

### コントローラ
教科書に従い、PostController.php の store メソッドに追記します。

バリデーションは $request にメソッドとして用意されており、
そこに配列でコントロールの名前と、バリデーション設定を渡して
$validated 変数に格納します。

そして、従来どおり Post::create にて投稿を行います。

::: note info
過去の session()->flash の行は一旦コメントアウトしました。
:::
### ビュー

コントローラにてバリデーションエラーを検出した場合、
ビュー側に $errors 変数が渡されるようです。

ビュー側では $errors->get('title') のように、
コントロールの名前を指定して、エラー文言を取得できます。

:::note info
バリデーションでエラーメッセージが出た際に、
ポストにて元の値が消えてしまっていては不便です。
old 関数でコントロール名を指定すると、元の値を取得できる
ので、old 関数にてエラー時に値が消えないようにします。
:::
バリデーションが効いていることが確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508336/506e7f27-d224-99e0-7b07-7cd8652e0d20.png)

# まとめ
以上、第５，６章でした。
DBアクセスと、フォームへの登録の内容でした。
セキュリティやユーザビリティを補う便利な機能が、
簡潔で一貫性のある記述で提供されていて、
Laravel フレームワークの高い完成度を感じました。

次は、７章以降、リレーションやミドルウェアなど
核心的な内容に入っていきます。

# 参考
- [Laravel – Userモデル](http://taustation.com/laravel-user-model/)
- [[laravel] controllerからviewへの変数の受け渡しとその展開方法
](https://qiita.com/ryo2132/items/63ced19601b3fa30e6de)
- [【Laravel】viewメソッドの使い方](https://tektektech.com/views-helper/)