【Laravel】書籍管理システムを作る(2)テーブル同士を紐付けるには?モデルのリレーション設定とセキュリティ対策(fillable)

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

Laravel による書籍管理システムの作成の第2回です。
今回は各テーブルにおける「リレーション」の設定を扱いたいと思います。

1. モデルファイルのリレーション設定

前回のポストで、テーブルのマイグレーションファイルを作成し、一緒にモデルファイルを作成しました。
モデルファイルは app/Models/ ディレクトリへ6個作成されてます。

  • app/Models/Author.php :著者
  • app/Models/Book.php :書籍(中心となるテーブル)
  • app/Models/Calligraphy.php :書影
  • app/Models/Category.php :カテゴリ(マスタ)
  • app/Models/Publisher.php :出版社(マスタ)
  • app/Models/Tag.php :タグ

このモデルファイルたちに、各テーブルの関係性であるリレーション設定を記入していきます。

1回目にも貼っつけましたが、ER図にすると以下のように、書籍テーブルを中心に各テーブルが紐づいているイメージです。

 

1-1. Book モデル

対象ファイル:app/Models/Book.php

書籍は「あるカテゴリ」に属し、「ある出版社」に属するためbelongsToを定義します。
また、著者、書影、タグに対しては、著者が「1」に対し書籍は「多」となるのでhasManyを設定します。

リレーションの考え方で一番わかり易いのは、例えば著者と書籍の場合の1対多の場合は、『田中芳樹は「銀河英雄伝説」、「アルスラーン戦記」、「創竜伝」など複数の作品を手掛けている』と考えるのが一番かと思われます。

 

belongsTo(多対1) の場合のアクション名(メソッド名)は単数形で、hasMany(1対多)の場合のアクション名(メソッド名)は複数形としていますが、わかりやすくするのが目的でそうなっているだけで、ここは自由に設定してもらっても問題ありません。
その様にするのが Laravelの流儀のようです。

 

1-2. Category モデル

対象ファイル:app/Models/Category.php

カテゴリは「複数の書籍」を持つため、hasMany を定義します。

 

1-3. Publisher モデル

対象ファイル:app/Models/Publisher.php

出版社も同様に「複数の書籍」を持つため、hasMany を定義します。

 

1-4. Author モデル

対象ファイル:app/Models/Author.php

著者は「ある書籍」に属するため、belongsTo を定義します。

 

1-5. Calligraphy モデル

対象ファイル:app/Models/Calligraphy.php

書影も「ある書籍」に属します。
テーブル名を単数形 calligraphy に指定している点に注意してください。

 

1-6. Tag モデル

対象ファイル:app/Models/Tag.php

タグも同様に「ある書籍」に属します。

 

これで全てのリレーション設定が完了しました。

1-7. データ取得、描画の使用イメージ

ちょっと気が早いですが、でっかくなので使用するイメージを。
コントローラーとかビューとか混じっていますが、下記のようにすると、書籍データからそれに紐づく著者や書影を一括で取得できるようになります。

 

1-8. fillable プロパティについて

1-8-1. 「fillable」 の概要

各モデルに登場する「fillable」についてですが、これはフォームなどのフロント部分からDBのカラムにデータ保存する際に、挿入する項目を指定するという働きを持つプロパティです。

下記はBookモデルの例。

 

id、created_at、updated_at など、自動で作成される項目以外を指定しています。
これで fillableプロパティに指定されたカラムにのみ、一括保存・更新処理が許可された ということになります。
いわゆるホワイトリスト形式でのセキュリティ対策ですね。

私が長年扱ってきたフレームワークである CakePHP の場合は、データベースにデータ保存するところで、カラム名と送信された内容を 'column' => $this->Post->name のように指定していましたが、Laravelの場合はもう少し楽に対策ができる、と考えればよいと思います。

そもそもの話ですが、Laravelでは fillable を定義しないと create()(新規登録) や update() (更新)を使った操作がエラーとなります。
これは「どのカラムにデータを入れていいかわからない」 ため、Laravelが安全のために操作を拒否している状態だからです。
データの新規登録、更新をする最には必ず定義する必要があるので、忘れすに定義しましょう。

1-8-2. guarded プロパティ

例えば登録するデータのカラムが100個あるようなシステムで fillable に100個のカラム名を指定をするのはあまり現実的ではない場合などには、除外するカラムを指定する形式である guarded プロパティを使用すると幸せになれるかもしれません。

例えば、下記のように除外するカラム「id」を指定すると、指定されたカラム以外を一括で保存・更新可能としてくれます。
指定カラム以外ですので、いわゆるブラックリストとなるわけです。
なるほどですね。

 

関連するポスト

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