Skip to content

Commit 0808926

Browse files
committed
Implement real-time factories within HasFactory
1 parent c70b64e commit 0808926

File tree

5 files changed

+74
-40
lines changed

5 files changed

+74
-40
lines changed

src/Illuminate/Database/Eloquent/Factories/Factory.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -813,11 +813,17 @@ public static function useNamespace(string $namespace)
813813
*
814814
* @param class-string<\Illuminate\Database\Eloquent\Model> $modelName
815815
* @return \Illuminate\Database\Eloquent\Factories\Factory
816+
*
817+
* @throws \Illuminate\Database\Eloquent\Factories\FactoryNotFoundException
816818
*/
817819
public static function factoryForModel(string $modelName)
818820
{
819821
$factory = static::resolveFactoryName($modelName);
820822

823+
if (! class_exists($factory)) {
824+
throw new FactoryNotFoundException($factory);
825+
}
826+
821827
return $factory::new();
822828
}
823829

@@ -906,10 +912,14 @@ public function __call($method, $parameters)
906912

907913
$relatedModel = get_class($this->newModel()->{$relationship}()->getRelated());
908914

909-
if (method_exists($relatedModel, 'newFactory')) {
910-
$factory = $relatedModel::newFactory() ?? static::factoryForModel($relatedModel);
911-
} else {
912-
$factory = static::factoryForModel($relatedModel);
915+
try {
916+
if (method_exists($relatedModel, 'newFactory')) {
917+
$factory = $relatedModel::newFactory() ?? static::factoryForModel($relatedModel);
918+
} else {
919+
$factory = static::factoryForModel($relatedModel);
920+
}
921+
} catch (FactoryNotFoundException $e) {
922+
$factory = $relatedModel::newRealTimeFactory();
913923
}
914924

915925
if (str_starts_with($method, 'for')) {
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace Illuminate\Database\Eloquent\Factories;
4+
5+
use RuntimeException;
6+
7+
class FactoryNotFoundException extends RuntimeException
8+
{
9+
/**
10+
* The factory that was not found.
11+
*
12+
* @var string
13+
*/
14+
public $factory;
15+
16+
/**
17+
* Create a new exception instance.
18+
*
19+
* @param string $factory
20+
* @return static
21+
*/
22+
public function __construct($factory)
23+
{
24+
parent::__construct("Call to undefined factory [{$factory}]");
25+
26+
$this->factory = $factory;
27+
}
28+
}

src/Illuminate/Database/Eloquent/Factories/HasFactory.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,29 @@ trait HasFactory
1313
*/
1414
public static function factory($count = null, $state = [])
1515
{
16-
$factory = static::newFactory() ?: Factory::factoryForModel(get_called_class());
16+
try {
17+
$factory = static::newFactory() ?: Factory::factoryForModel(get_called_class());
18+
} catch (FactoryNotFoundException $e) {
19+
$factory = static::newRealTimeFactory();
20+
}
1721

1822
return $factory
1923
->count(is_numeric($count) ? $count : null)
2024
->state(is_callable($count) || is_array($count) ? $count : $state);
2125
}
2226

27+
/**
28+
* Create a new factory instance for the model.
29+
*
30+
* @return \Illuminate\Database\Eloquent\Factories\Factory<static>
31+
*/
32+
protected static function newRealTimeFactory()
33+
{
34+
return (new RealTimeFactory)
35+
->forModel(get_called_class())
36+
->configure();
37+
}
38+
2339
/**
2440
* Create a new factory instance for the model.
2541
*

src/Illuminate/Database/Eloquent/Factories/HasRealTimeFactory.php

Lines changed: 0 additions & 20 deletions
This file was deleted.

tests/Database/RealTimeFactoryTest.php

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use Illuminate\Database\Eloquent\Casts\AsEncryptedCollection;
1515
use Illuminate\Database\Eloquent\Casts\AsEnumCollection;
1616
use Illuminate\Database\Eloquent\Factories\Factory;
17-
use Illuminate\Database\Eloquent\Factories\HasRealTimeFactory;
17+
use Illuminate\Database\Eloquent\Factories\HasFactory;
1818
use Illuminate\Database\Eloquent\Model as Eloquent;
1919
use Illuminate\Database\QueryException;
2020
use Illuminate\Encryption\Encrypter;
@@ -581,7 +581,7 @@ public function testItCanHandleManyToManyPolymorphicRelationships()
581581

582582
public function testItCanBeUsedToDefineARelationWithinAFactory()
583583
{
584-
$post = PostFactory::new()->create();
584+
$post = PostDummyFactory::new()->create();
585585

586586
$this->assertNotNull($post->user);
587587
}
@@ -598,7 +598,7 @@ public function testRealTimeFactoriesCannotBeInstantiatedWithNew()
598598
$this->expectException(\RuntimeException::class);
599599
$this->expectExceptionMessage('Real-time factories cannot be instantiated with new()');
600600

601-
Post::factory()->times(3);
601+
User::factory()->times(3);
602602
}
603603

604604
public function testIgnoresPrimaryAndForeignKeysFromDefinition()
@@ -612,7 +612,7 @@ public function testIgnoresPrimaryAndForeignKeysFromDefinition()
612612

613613
class Cast extends Eloquent
614614
{
615-
use HasRealTimeFactory;
615+
use HasFactory;
616616

617617
protected $casts = [
618618
'array_column' => 'array',
@@ -648,27 +648,27 @@ class Cast extends Eloquent
648648

649649
class Type extends Eloquent
650650
{
651-
use HasRealTimeFactory;
651+
use HasFactory;
652652
}
653653

654654
class Nullable extends Eloquent
655655
{
656-
use HasRealTimeFactory;
656+
use HasFactory;
657657
}
658658

659659
class Guess extends Eloquent
660660
{
661-
use HasRealTimeFactory;
661+
use HasFactory;
662662
}
663663

664664
class Key extends Eloquent
665665
{
666-
use HasRealTimeFactory;
666+
use HasFactory;
667667
}
668668

669669
class User extends Eloquent
670670
{
671-
use HasRealTimeFactory;
671+
use HasFactory;
672672

673673
public function posts()
674674
{
@@ -685,7 +685,7 @@ public function roles()
685685

686686
class Post extends Eloquent
687687
{
688-
use HasRealTimeFactory;
688+
use HasFactory;
689689

690690
protected $casts = [
691691
'published' => 'boolean',
@@ -711,7 +711,7 @@ public function tags()
711711

712712
class Role extends Eloquent
713713
{
714-
use HasRealTimeFactory;
714+
use HasFactory;
715715

716716
public function users()
717717
{
@@ -723,7 +723,7 @@ public function users()
723723

724724
class Comment extends Eloquent
725725
{
726-
use HasRealTimeFactory;
726+
use HasFactory;
727727

728728
public function commentable()
729729
{
@@ -733,7 +733,7 @@ public function commentable()
733733

734734
class Tag extends Eloquent
735735
{
736-
use HasRealTimeFactory;
736+
use HasFactory;
737737

738738
public function posts()
739739
{
@@ -743,10 +743,10 @@ public function posts()
743743

744744
class ReservedWord extends Eloquent
745745
{
746-
use HasRealTimeFactory;
746+
use HasFactory;
747747
}
748748

749-
class PostFactory extends Factory
749+
class PostDummyFactory extends Factory
750750
{
751751
protected $model = Post::class;
752752

0 commit comments

Comments
 (0)