问题
UPDATE (SOLUTION)
- If you need
->userrelationship from one of the$imageinside$user->images, then$uservariable is already available cause you loaded the->imagesfrom it! - Don't use
protected $withEloquent property. It's an anti-pattern. - Instead explicitly eager load relationships on-demand from where/when it's needed (Note: it should not prevent you to keep things DRY!)
- If you really need/want to, see @nicksonyap answer. It does the trick (I believe – not tested).
ORIGINAL
I'm running into what I believe is a simple problem:
- I have a
Userobject that has manyImages Imagebelongs toUser... (inverse relation)
My problem is that I want to eager load both the images() on the User model and the user() on the Image model. To do so, I just setup a $with property as explained in the docs.
My User model:
class User extends EloquentModel {
protected $with = ['images'];
public function images()
{
return $this->hasMany(Image::class);
}
}
My Image model:
class Image extends EloquentModel {
protected $with = ['user'];
public function user()
{
return $this->belongsTo(User::class);
}
}
But when performing:
$user = User::find(203);
This results in an infinite loop (php segmentation fault). There must be some kind of circular reference that I am not able to locate:
[1] 85728 segmentation fault
EDIT 2016/02
This is the simplest "Workaround" I found:
// User.php
public function setRelation($relation, $value)
{
if ($relation === 'images') {
foreach ($value as $image) {
$image->setUser($this);
}
}
return parent::setRelation($relation, $value);
}
回答1:
There is a without() method: https://laravel.com/api/5.8/Illuminate/Database/Eloquent/Builder.html#method_without
Placing without() on both sides of a relationship worked.
class Property extends EloquentModel {
protected $with = ['images'];
public function images()
{
return $this->hasMany(Image::class)->without('property');
}
}
class Image extends EloquentModel {
protected $with = ['property'];
public function property()
{
return $this->belongsTo(Property::class)->without('images');
}
public function getAlt()
{
return $this->property->title;
}
}
回答2:
When you try to find a Property, that property eager loads all the images it has and every Image eager loads the property it belongs to, which is the property you try to find, which will again start to eager load all the images it has. etc...
The way I would resolve this problem is by not eager loading inside the models, but by eager loading when calling the models.
so using the following:
$prop = Property::with('images')->find(203);
while removing this line in the Property model:
protected $with = ['images'];
And this line in the Image model:
protected $with = ['property'];
I hope this solution works for you.
来源:https://stackoverflow.com/questions/34995187/eager-load-hasmany-belongsto-circular-reference-infinite-loop