【Laravel】書籍管理システムを作る(5)登録フォーム作成とバリデーション・DB保存

Laravel
記事内に広告が含まれています。

Laravelによる書籍管理システムの作成、第5回です。
今回は書籍の登録フォームを作成し、データベースにデータを登録する作成手順を追って行きたいと思います。

1. ルーティングの設定

1-1. 認証必要ルートに追加

「認証(ログイン)している人だけ」がアクセスできるグループの中に、登録用のルートを2つ作成します。
連載を読んでいる場合、前回のポストで作成したルーティングの、3番、4番のコメントアウトを外せばOKです。

編集ファイル: routes/web.php

以前のポストにも書きましたが、最後の ->name() でそれぞれ create と store と名付けて、ビューから呼べるようにしています。
地味に便利。

1-2. ルート設定の追記(404エラー対策)

ルート設定ですが、前回のポストで書いたとおりにしていると create 画面に入ったときに 404エラー が表示されてしまいました。
原因は Laravel のルーティングは 上から順番に 判定されるからでした。

というのも、もし web.php で、詳細画面({book})の定義が、新規作成(create)よりも  に書いてあると、Laravel は「create という名前の書籍データを探そう」としてしまい、見つからずに404エラーを出してしまいます。

正しくルーティングを行うよう、/books/books/{book} の記述を下記のように、/books/create よりも後で定義するように修正してください。

編集ファイル: routes/web.php

↑ 認証しなくてもよい【グループ外】の記述を、後で評価するようにしています。

また、create フォームを表示させたい際は、ログイン認証を行ったあとでアクセスする必要があることをお忘れなく。

2. コントローラーの編集

2-1. フォーム用メソッドと、保存処理メソッドを作成する

登録画面では、「カテゴリ」や「出版社」を選択肢(プルダウン)として出す必要があるため、それらのデータを取得してビューに渡します。

編集ファイル: BookController.php

 

2-2. プルダウン用データの取得

2-2-1. スコープなしの論理削除の場合(第一弾)

テーブルを設計する際、論理削除での仕様を考えたため、レコード取得の際は(削除フラグが0の場合)という条件を付与する必要があります。
なので、まず思いつくのが下記の形だと思います。

 

2-2-2. スコープを採用(第二弾)

「論理削除されていないデータだけを取得する」という処理は、登録画面だけでなく、一覧画面や他の場所でも何度も使います。そのたびに where('is_deleted', 0) と書くと、もし将来「1を有効、0を削除」に変更したくなったときに修正が大変です。

そこで、モデル側に 「ローカルスコープ」 という名前を付けた条件を定義しておくのが一般的です。

手順1. モデルにスコープを定義

App\Models\Category.php および App\Models\Publisher.php に以下を追記します。
なお、この際にメソッド名を scopeXXXX とすると、呼び出すときに XXXX() という名前で使えます。

 

手順2. コントローラーで呼び出す

コントローラーが非常に読みやすくなります。

 

2-2-3. マジックナンバーを避ける

where('is_deleted', 0) の 0 のような数字を直接コードに書き続けると、後で意味がわからなくなりがちです。今回のように「Active」という名前を付ける(スコープ化する)ことで、「何をしているコードか」が誰が見ても一目でわかるようになります。

まずは「スコープなし」で動作を確認し、慣れてきたら「スコープあり」に挑戦してコードを綺麗に保つのがおすすめ。
慣れる意味もこめて、スコープありのコード体系を構築しましょう。

ということで、上記手順1および2を実施し、スコープありのコードを採用することにします。

2-3. 論理削除について思うこと

テーブル設定で論理削除を是とするか否とするかは、本当にいろんな考えがあると思います。
その方法としても、今回は単純なフラグとしての is_deleted カラムを採用しましたが、削除の場合に日時を登録する方式(deleted_at)など、こちらも色々通ると思われます。

これは一概にどの方法が良いという答えはなく、プロジェクトやシステムに合った方式を熟考するというのが一般的な考えだと思われます。

また、論理削除ではないテーブル構造(=物理削除)の場合では全件を取得すれば良いとなるので、下記の取得方法でOKとなります。

 

2-3-1. レコードの取得方法について

今更ですが、レコードの取得方法について。

上で挙げた all() は「テーブルの全データを無条件で取ってくる」というメソッドです。これは楽に使えます。
逆に条件を付け加えたいときは、クエリビルダという「条件を組み立てる道具」の where() を使い、最後に get() で実行するという流れになります。

参考ですが、クエリビルダで is_deleted0 という条件式は以下のように書きます。

 

3. バリデーションについて

3-1. 代表的なバリデーションルール

バリデーションの書き方と意味について軽くまとめます。
代表的なものを少し挙げると、下記のようなものがあります。

Laravelのバリデーションルール例
バリデーションルール チェックする内容
integer 整数値かどうか
max: 値 指定した値以下かどうか
min: 値 指定した値以上かどうか
requierd 値が入っているかどうか
size: 値 指定した値と同じサイズ / 文字数かどうか

他にも様々なバリデーションルールがありますので、公式マニュアルを読むのも良いでしょう。

 

3-2. 今回使用するバリデーションルール

今回のルールとして採用したものを見ていきましょう。
1項目につき複数のルールを当てる場合は | (パイプ文字)で区切ることで可能です。

 

‘title’ => ‘required|max:255’,
「必須」、「文字数255文字以下であること」という入力ルールとなります。

‘category_id’ => ‘required|exists:m_categories,id’,
exists : データベーステーブル名, カラム名 と明示的に指定することができます。
なので「m_categories テーブルの id カラムの値に含まれている値であること」というルールとなります。

‘publisher_id’ => ‘required|exists:m_publishers,id’,
同様に、「m_publishers テーブルの id カラム値に含まれている値であること」というルールとなります。

‘price’ => ‘nullable|numeric|min:0’,
「フィールドが null 値であることを許容」、「フィールドは数値であること」、「フィールドは0 以上であること」というルールとなります。

‘description’ => ‘nullable|string’,
「フィールドが null 値であることを許容」、「文字列タイプであること」というルールとなります。

 

4. ビューの作成

4-1. 登録フォーム

Breezeのコンポーネントスタイル(<x-app-layout>)で作成します。
前回でも書きましたが、ビューファイルには作成コマンドは無く、手動でファイルを作成します。

編集ファイル: resources/views/books/create.blade.php

 

4-2. ビュー作成におけるポイント解説

4-2-1. @csrf とは?

フォームの中に必ず書く「おまじない」です。
これは 「クロスサイト・リクエスト・フォージェリ」(CSRF) という攻撃を防ぐためのセキュリティトークンを発行します。これがないと、Laravelはセキュリティエラー(419エラー)を出して保存を拒否します。

以下は参考記事。

 

4-2-2. old('title') とは?

もし入力内容にミス(バリデーションエラー)があって画面が戻ってきたとき、「先程まで入力していた内容」 を消さずに残しておくための便利な機能です。

 

4-2-3. バリデーションエラーの表示

エラーがあった場合、フォームの上部にまとめて表示しています。

 

エラーの有無は 「any()」 で判定が可能です。コレクションの要素(この場合はエラーメッセージ)が1つでも存在するかどうかをチェックし、存在すれば trueを返します。
@if (count($errors) > 0) のようにして判定も可能ですが、より洗練された書き方を使うのが良さそうです。

4-3. 画面キャプチャ

今回作成した画面のキャプチャです。

4-3-1. 書籍登録画面全体

書籍登録画面です。
最低限の登録フォームのみです。(ISBNコード、発行年、タグなどは未実装)

 

4-3-2. カテゴリ・出版社(プルダウン)

カテゴリと出版社はプルダウンで選択できるようになっています。

 

 

4-3-3. バリデーションエラーの表示

何も入力せずに「登録する」ボタンを押下した場合。
タイトル、カテゴリ、出版社のバリデーションエラーとなります。

 

4-3-4. old() テスト

タイトルに「Javascript逆引きレシピ」と入力しした場合。
カテゴリ、出版社のバリデーションエラーとなりメッセージが表示されるのと、入力したタイトル用フォームに「Javascript逆引きレシピ」がそのまま残っています。
old() が効いているということですね。

 

4-3-5. 入力テスト

タイトル:テスト書籍1
カテゴリ:文芸書
出版社:株式会社 石田
概要:1
で登録ボタン押下します。

 

4-3-6. 登録後一覧画面

登録後の一覧ページの3ページ目の画面です。

 

4-3-7. 新規登録データの詳細画面

新規登録データの詳細ページです。

 

以上で、ひとまず最低限ですが CRUD の C と R が完成しました。
引き続き、不足している項目の追加、画像投稿、その後に 更新、削除と続けていきたいと思います。

関連するポスト

 

タイトルとURLをコピーしました