この組み合わせは、いま最も選ばれやすい組み合わせではないでしょうか。 この土台を作るだけでも選択肢や注意するべきポイントが沢山あって一苦労です。 プログラマーならコードで語れ!というように、ボイラープ…
Laravelの標準では、「app/Models/」にLaravelのORマッパーである Eloquent(エロクアント)
のモデルを配置します。
要はデータベースのテーブルと対になるオブジェクトです。
連載
本記事は複数記事の連載記事の1つです。
この記事に関連するコミット
DDDのエンティティとして使って良いのか?
エンティティはテーブルと対になるオブジェクトである必要はなく、アプリケーションとして意味のある単位としてあるべきです。(2つのテーブルから1つのエンティティとしてもOK)
また、Eloquentのモデルにはテーブル名やリレーション等の定義が入るため、一緒にしてしまうとドメインの責務と混ざってしまいます。
とは言え、 細かいことは良いんだ!軽量DDDだから似たようなもんだし使っちゃえ!
といったようにモデルをエンティティとしても使いたくなりますが、辞めておいたほうが良いでしょう。
Userモデルで例を挙げると、継承しているEloquentのモデルクラスによって以下のようにデータベースのアクセス、プロパティへの値のセット、保存が出来ます。
つまり、Eloquentのモデルクラスによって何でもやりたい放題のエンティティ
になってしまいます。
このアプリはユーザー名は一度決めたら変えられない仕様
なのでドメインでチェックして防ぎたいと思っても防ぎようがありません。
// データベースにアクセスしてID:1のユーザーを取得 $user = User::find(1); // ユーザー名を変更 $user->name = 'changed name'; // データベースに変更内容を保存 $user->save();
ORマッパー用のモデルとエンティティを分ける
以下のディレクトリ構成でORマッパー用のモデルとエンティティを分けます。
種別 | 役割 | ディレクトリ | サンプル |
---|---|---|---|
ORマッパー用のモデル | データベースへ読み書きするモデル | app/Models | OrderModel.php |
エンティティ | アプリケーションのビジネス知識を表現するモデル | packages/domains | Order.php |
データベースから取得する流れ場合は、
データベース → ORマッパー用のモデル → エンティティと変換します。
データベースへ永続化する場合は、
エンティティ → ORマッパー用のモデル → データベースと変換します。
詳しくは別途リポジトリの記事に記載します。
ORマッパー用のモデルのディレクトリについて
Laravel経験者を採用してもフレームワークとしての標準から構成を変えるほど、学習コストが高くなってしまいます。
また、Artisanコマンドもパスが違うと使えなくなります。
そのため、サンプルではLaravel標準の「app/Models」にしています。
そのトレードオフとしてModelsだけレイヤーの概念から外れてLaravelディレクトリ郡にいることが違和感でもあるため、インフラストラクチャ層などに置いてしまっても構わないと思います。
オートローダーの設定
ルートディレクトリにpackagesディレクトリを追加し、Orderを追加しました。
php artisan tinker
コマンドでREPL(対話型コンソール)を立ち上げ、インスタンスを生成してみます。
Packages\Domains\Orders\Order::create('num');
「not found」とクラスが見つからないとエラーが表示されます。
PHP Error: Class "Packages\Domains\Orders\Order();" not found in Psy Shell code on line 1
これは入力ミスなどではなく、PHPの名前・ディレクトリパスの解決をしてくれるオートローディングの対象ディレクトリに「packages」が含まれていないため発生します。
指定方法はcomposer.json
の’autoload’に以下のように追加します。
composer.json "autoload": { "psr-4": { "App\\": "app/", "Database\\Factories\\": "database/factories/", "Database\\Seeders\\": "database/seeders/", "Packages\\": "packages/" } },
追加しただけではダメで、変更を反映するには以下のコマンドを実行します。
composer dump-autoload
コメントを書く