Laravel 8.x にアップグレードする時
特に影響の可能性が高いのが、下記に記載されているファクトリの変更です。
https://readouble.com/laravel/8.x/ja/upgrade.html#model-factoriesドキュメントに記載されているように、laravel/legacy-factories
をインストールすれば、Laravel7.xの書き方のままで問題ありませんが、
legacy-factory
という名前にも入っているようにlegacyなので、出来ればLaravel8.xのfactoryの書き方に修正したい、となった時に
以下のサイトが参考になります。
https://tech.sumzap.co.jp/entry/laravel-version-uphttps://zenn.dev/naopusyu/articles/e3e8d010c4e245
factoryの書き方修正でのハマりポイントがあったのでメモ
上記のサイトを参考に、一通りfactoryを書き換えて試しにSeederあるいはTestを実行すると、以下のエラーが出ました。
Class "Database\Factories\Eloquent\SampleFactory" not found
どうやらSampleFactoryが見つからない様子です。
FactoryのnamespaceをDatabase\Factories
からDatabase\Factories\Eloquent
に修正してみたが解決しません。
続いて、composer dump-autoload
も試しましたが駄目でした。
色々と調査した結果、解決方法は2つありそうです。
- ディレクトリ構成 と namespaceを合わせる
database/factories/SampleFactory.php
から、
database/factories/Eloquent/SampleFactory.php
に修正する。
SampleFactoryのnamespaceもDatabase\Factories\Eloquent
にします。
- newFactory()をモデルに定義する
1が何らかの理由でダメな場合はこっちですかね。例えばfactories配下のディレクトリ構成を変えた時の影響範囲が広すぎるからやりたくない、とか。
factoryについてのドキュメントを改めて読み込むと、以下の文章が記載されています。
HasFactoryトレイトのfactoryメソッドは規約に基づいて、その トレイトが割り当てられているモデルに適したファクトリを決定します。具体的には、Database\Factories名前空間の中でモデル名と一致するクラス名を持ち、サフィックスがFactoryであるファクトリを探します。この規約を特定のアプリケーションやファクトリで適用しない場合は、モデルのnewFactoryメソッドを上書きし、モデルと対応するファクトリのインスタンスを直接返してください。
下記の様にモデルクラスにXXXFactoryのインスタンスを返すnewFactory()という関数を定義してくださいね、ということらしい。
use Database\Factories\Eloquent\SampleFactory;
/**
* モデルの新ファクトリ・インスタンスの生成
*
* @return \Illuminate\Database\Eloquent\Factories\Factory
*/
protected static function newFactory()
{
return SampleFactory::new();
}
次に、対応するファクトリで、modelプロパティを定義します。
use App\Eloquent\Sample;
use Illuminate\Database\Eloquent\Factories\Factory;
class SampleFactory extends Factory
{
/**
* モデルと対応するファクトリの名前
*
* @var string
*/
protected $model = Sample::class;
}
ちょっとしたハマりポイントでした。