Laravel 8 基于类的模型工厂

Posted

技术标签:

【中文标题】Laravel 8 基于类的模型工厂【英文标题】:Laravel 8 Class Based Model Factories 【发布时间】:2020-12-28 21:56:13 【问题描述】:

我试图弄清楚为什么当我尝试创建我的 Player 类和 dd($this) 的工厂时,它会返回,因为它没有覆盖模型的状态。同样没有意义的是,它是状态的两个项目的集合。

任何人都可以对此进行进一步澄清吗?

$player = Player::factory()->injured()->create();


<?php

namespace Database\Factories;

use App\Enums\PlayerStatus;
use App\Models\Player;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;

class PlayerFactory extends Factory

    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected string $modelClass = Player::class;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition(): array
    
        return [
            'name' => $this->faker->name,
            'height' => $this->faker->numberBetween(60, 95),
            'weight' => $this->faker->numberBetween(180, 500),
            'hometown' => $this->faker->city.', '.$this->faker->state,
            'status' => PlayerStatus::__default,
        ];
    

    public function injured(): self
    
        $this->state([
            'status' => PlayerStatus::INJURED,
        ]);

        dd($this);

        $now = now();
        $start = $now->copy()->subDays(2);

        $this->hasEmployments(1, ['started_at' => $start]);

        $this->hasInjuries(1, ['started_at' => $now]);

        return $this;
    



    ^ Database\Factories\PlayerFactory^ #2650
  #modelClass: "App\Models\Player"
  #model: null
  #count: null
  #states: Illuminate\Support\Collection^ #2647
    #items: array:2 [
      0 => Closure()^ #2631
        class: "Illuminate\Database\Eloquent\Factories\Factory"
        this: Database\Factories\PlayerFactory #2626 …
        use: 
          $state: []
        
      
      1 => Closure()^ #2646
        class: "Illuminate\Database\Eloquent\Factories\Factory"
        this: Database\Factories\PlayerFactory #2648 …
        use: 
          $state: []
        
      
    ]
  
  #has: Illuminate\Support\Collection^ #2610
    #items: []
  
  #for: Illuminate\Support\Collection^ #2640
    #items: []
  
  #afterMaking: Illuminate\Support\Collection^ #2455
    #items: []
  
  #afterCreating: Illuminate\Support\Collection^ #2453
    #items: []
  
  #connection: null
  #faker: null

【问题讨论】:

【参考方案1】:

方法调用:

$this->state([
        'status' => PlayerStatus::INJURED,
]);

不修改当前对象 - 它使用更新的“状态”创建一个新的工厂实例。而这个新的工厂应该由受伤的方法返回。

在这种情况下,一种解决方案是:

public function injured(): self

    $injuredPlayer = $this->state([
        'status' => PlayerStatus::INJURED,
    ]);

    $now = now();
    $start = $now->copy()->subDays(2);

    $injuredPlayer->hasEmployments(1, ['started_at' => $start]);

    $injuredPlayer->hasInjuries(1, ['started_at' => $now]);

    return $injuredPlayer;

【讨论】:

以上是关于Laravel 8 基于类的模型工厂的主要内容,如果未能解决你的问题,请参考以下文章

laravel 8中扩展模型的工厂

Laravel 8 在模型工厂中定义 belongsToMany 定义

Laravel 8 工厂类在创建工厂时不会覆盖参数

laravel 工厂模式到容器

laravel 服务容器的由来 代码展示

Laravel 8 工厂的多重关系