Skip to content

Commit a5eaf42

Browse files
authored
[12.x] Resolve issue with Factory make when automatic eager loading (#56211)
* init * cs * cs
1 parent 5ad0a1c commit a5eaf42

File tree

2 files changed

+101
-15
lines changed

2 files changed

+101
-15
lines changed

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

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -394,27 +394,37 @@ public function makeOne($attributes = [])
394394
*/
395395
public function make($attributes = [], ?Model $parent = null)
396396
{
397-
if (! empty($attributes)) {
398-
return $this->state($attributes)->make([], $parent);
399-
}
397+
$autoEagerLoadingEnabled = Model::isAutomaticallyEagerLoadingRelationships();
400398

401-
if ($this->count === null) {
402-
return tap($this->makeInstance($parent), function ($instance) {
403-
$this->callAfterMaking(new Collection([$instance]));
404-
});
399+
if ($autoEagerLoadingEnabled) {
400+
Model::automaticallyEagerLoadRelationships(false);
405401
}
406402

407-
if ($this->count < 1) {
408-
return $this->newModel()->newCollection();
409-
}
403+
try {
404+
if (! empty($attributes)) {
405+
return $this->state($attributes)->make([], $parent);
406+
}
407+
408+
if ($this->count === null) {
409+
return tap($this->makeInstance($parent), function ($instance) {
410+
$this->callAfterMaking(new Collection([$instance]));
411+
});
412+
}
410413

411-
$instances = $this->newModel()->newCollection(array_map(function () use ($parent) {
412-
return $this->makeInstance($parent);
413-
}, range(1, $this->count)));
414+
if ($this->count < 1) {
415+
return $this->newModel()->newCollection();
416+
}
417+
418+
$instances = $this->newModel()->newCollection(array_map(function () use ($parent) {
419+
return $this->makeInstance($parent);
420+
}, range(1, $this->count)));
414421

415-
$this->callAfterMaking($instances);
422+
$this->callAfterMaking($instances);
416423

417-
return $instances;
424+
return $instances;
425+
} finally {
426+
Model::automaticallyEagerLoadRelationships($autoEagerLoadingEnabled);
427+
}
418428
}
419429

420430
/**

tests/Integration/Database/EloquentModelRelationAutoloadTest.php

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace Illuminate\Tests\Integration\Database\EloquentModelRelationAutoloadTest;
44

55
use DB;
6+
use Illuminate\Database\Eloquent\Factories\Factory;
7+
use Illuminate\Database\Eloquent\Factories\HasFactory;
68
use Illuminate\Database\Eloquent\Model;
79
use Illuminate\Database\Schema\Blueprint;
810
use Illuminate\Support\Facades\Schema;
@@ -12,6 +14,13 @@ class EloquentModelRelationAutoloadTest extends DatabaseTestCase
1214
{
1315
protected function afterRefreshingDatabase()
1416
{
17+
Schema::create('tags', function (Blueprint $table) {
18+
$table->increments('id');
19+
$table->string('name')->nullable();
20+
$table->string('status')->nullable();
21+
$table->unsignedInteger('post_id')->nullable();
22+
});
23+
1524
Schema::create('posts', function (Blueprint $table) {
1625
$table->increments('id');
1726
});
@@ -214,6 +223,63 @@ public function testRelationAutoloadVariousNestedMorphRelations()
214223

215224
DB::disableQueryLog();
216225
}
226+
227+
public function testRelationAutoloadWorksOnFactoryMake()
228+
{
229+
Model::automaticallyEagerLoadRelationships();
230+
231+
DB::enableQueryLog();
232+
233+
$tags = Tag::factory()->times(3)->make();
234+
235+
$post = Post::create();
236+
237+
$post->tags()->saveMany($tags);
238+
239+
$this->assertCount(7, DB::getQueryLog());
240+
241+
Model::automaticallyEagerLoadRelationships(false);
242+
243+
DB::disableQueryLog();
244+
}
245+
}
246+
247+
class TagFactory extends Factory
248+
{
249+
protected $model = Tag::class;
250+
251+
public function definition()
252+
{
253+
return [];
254+
}
255+
}
256+
257+
class Tag extends Model
258+
{
259+
use HasFactory;
260+
261+
public $timestamps = false;
262+
263+
protected $guarded = [];
264+
265+
protected static function booted()
266+
{
267+
static::creating(function ($model) {
268+
if ($model->post->shouldApplyStatus()) {
269+
$model->status = 'Todo';
270+
}
271+
});
272+
}
273+
274+
protected static function newFactory()
275+
{
276+
return TagFactory::new();
277+
}
278+
279+
public function post()
280+
{
281+
return $this->belongsTo(Post::class);
282+
}
217283
}
218284

219285
class Comment extends Model
@@ -242,6 +308,11 @@ class Post extends Model
242308
{
243309
public $timestamps = false;
244310

311+
public function shouldApplyStatus()
312+
{
313+
return false;
314+
}
315+
245316
public function comments()
246317
{
247318
return $this->morphMany(Comment::class, 'commentable');
@@ -256,6 +327,11 @@ public function likes()
256327
{
257328
return $this->morphMany(Like::class, 'likeable');
258329
}
330+
331+
public function tags()
332+
{
333+
return $this->hasMany(Tag::class);
334+
}
259335
}
260336

261337
class Video extends Model

0 commit comments

Comments
 (0)