Skip to content

Commit 56466a9

Browse files
committed
Merge branch 'lazy-loading' into 8.x
2 parents 5a92f04 + c986e12 commit 56466a9

File tree

3 files changed

+92
-1
lines changed

3 files changed

+92
-1
lines changed

src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ public function getRelationValue($key)
439439
}
440440

441441
if ($this->preventsLazyLoading) {
442-
throw new LazyLoadingViolationException($this, $key);
442+
$this->handleLazyLoadingViolation($key);
443443
}
444444

445445
// If the "attribute" exists as a method on the model, we will just assume
@@ -460,6 +460,21 @@ public function isRelation($key)
460460
(static::$relationResolvers[get_class($this)][$key] ?? null);
461461
}
462462

463+
/**
464+
* Handle a lazy loading violation.
465+
*
466+
* @param string $key
467+
* @return mixed
468+
*/
469+
protected function handleLazyLoadingViolation($key)
470+
{
471+
if (isset(static::$lazyLoadingViolationCallback)) {
472+
return call_user_func(static::$lazyLoadingViolationCallback, $this, $key);
473+
}
474+
475+
throw new LazyLoadingViolationException($this, $key);
476+
}
477+
463478
/**
464479
* Get a relationship value from a method.
465480
*

src/Illuminate/Database/Eloquent/Model.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,13 @@ abstract class Model implements Arrayable, ArrayAccess, Jsonable, JsonSerializab
158158
*/
159159
protected static $modelsShouldPreventLazyLoading = false;
160160

161+
/**
162+
* The callback that is responsible for handling lazy loading violations.
163+
*
164+
* @var callable|null
165+
*/
166+
protected static $lazyLoadingViolationCallback;
167+
161168
/**
162169
* The name of the "created at" column.
163170
*
@@ -358,6 +365,17 @@ public static function preventLazyLoading($value = true)
358365
static::$modelsShouldPreventLazyLoading = $value;
359366
}
360367

368+
/**
369+
* Register a callback that is responsible for handling lazy loading violations.
370+
*
371+
* @param callable $callback
372+
* @return void
373+
*/
374+
public static function handleLazyLoadingViolationUsing(callable $callback)
375+
{
376+
static::$lazyLoadingViolationCallback = $callback;
377+
}
378+
361379
/**
362380
* Fill the model with an array of attributes.
363381
*

tests/Integration/Database/EloquentStrictLoadingTest.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,35 @@ public function testStrictModeThrowsAnExceptionOnLazyLoadingInRelations()
100100

101101
$models[0]->modelTwos[0]->modelThrees;
102102
}
103+
104+
public function testStrictModeWithCustomCallbackOnLazyLoading()
105+
{
106+
$this->expectsEvents(ViolatedLazyLoadingEvent::class);
107+
108+
Model::handleLazyLoadingViolationUsing(function ($model, $key) {
109+
event(new ViolatedLazyLoadingEvent($model, $key));
110+
});
111+
112+
EloquentStrictLoadingTestModel1::create();
113+
EloquentStrictLoadingTestModel1::create();
114+
115+
$models = EloquentStrictLoadingTestModel1::get();
116+
117+
$models[0]->modelTwos;
118+
}
119+
120+
public function testStrictModeWithOverriddenHandlerOnLazyLoading()
121+
{
122+
$this->expectException(\RuntimeException::class);
123+
$this->expectExceptionMessage('Violated');
124+
125+
EloquentStrictLoadingTestModel1WithCustomHandler::create();
126+
EloquentStrictLoadingTestModel1WithCustomHandler::create();
127+
128+
$models = EloquentStrictLoadingTestModel1WithCustomHandler::get();
129+
130+
$models[0]->modelTwos;
131+
}
103132
}
104133

105134
class EloquentStrictLoadingTestModel1 extends Model
@@ -114,6 +143,23 @@ public function modelTwos()
114143
}
115144
}
116145

146+
class EloquentStrictLoadingTestModel1WithCustomHandler extends Model
147+
{
148+
public $table = 'test_model1';
149+
public $timestamps = false;
150+
protected $guarded = [];
151+
152+
public function modelTwos()
153+
{
154+
return $this->hasMany(EloquentStrictLoadingTestModel2::class, 'model_1_id');
155+
}
156+
157+
protected function handleLazyLoadingViolation($key)
158+
{
159+
throw new \RuntimeException("Violated {$key}");
160+
}
161+
}
162+
117163
class EloquentStrictLoadingTestModel2 extends Model
118164
{
119165
public $table = 'test_model2';
@@ -132,3 +178,15 @@ class EloquentStrictLoadingTestModel3 extends Model
132178
public $timestamps = false;
133179
protected $guarded = [];
134180
}
181+
182+
class ViolatedLazyLoadingEvent
183+
{
184+
public $model;
185+
public $key;
186+
187+
public function __construct($model, $key)
188+
{
189+
$this->model = $model;
190+
$this->key = $key;
191+
}
192+
}

0 commit comments

Comments
 (0)