1<?php
2
3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0.
4// See the LICENCE file in the repository root for full licence text.
5
6declare(strict_types=1);
7
8namespace Database\Factories;
9
10use App\Exceptions\ModelNotSavedException;
11use Illuminate\Database\Eloquent\Factories\Factory as BaseFactory;
12use Illuminate\Database\Eloquent\Model;
13use Illuminate\Support\Collection;
14
15abstract class Factory extends BaseFactory
16{
17 private bool $requireSaved = true;
18
19 /**
20 * Return the created model even if it fails to save.
21 *
22 * @return $this
23 */
24 public function allowUnsaved(): static
25 {
26 $this->requireSaved = false;
27
28 return $this;
29 }
30
31 protected function callAfterCreating(Collection $instances, ?Model $parent = null): void
32 {
33 if ($this->requireSaved) {
34 $instances->each(function ($model) {
35 if (!$model->exists) {
36 throw new ModelNotSavedException(
37 method_exists($model, 'validationErrors')
38 ? $model->validationErrors()->toSentence()
39 : 'Failed to save model',
40 );
41 }
42 });
43 }
44
45 parent::callAfterCreating($instances, $parent);
46 }
47
48 protected function newInstance(array $arguments = []): static
49 {
50 $factory = parent::newInstance($arguments);
51 $factory->requireSaved = $this->requireSaved;
52
53 return $factory;
54 }
55}