Laravel 5 急切的负载有许多&;belongsTo(循环参考/无限循环)

Laravel 5 急切的负载有许多&;belongsTo(循环参考/无限循环),laravel-5,eloquent,eager-loading,Laravel 5,Eloquent,Eager Loading,更新(解决方案) 如果您需要->user中的$image关系,则$user变量已经可用,因为您从中加载了->images 不要将受保护的$与雄辩的属性一起使用。这是一种反模式 相反,在需要的位置/时间,显式地按需加载关系(注意:这不应阻止您保持干燥!) 如果您确实需要/想要,请参阅@nicksonyap-answer。它起到了作用(我相信——未经测试) 原创 我遇到了一个我认为很简单的问题: 我有一个用户对象,它有许多图像s 图像属于用户。。。(逆关系) 我的问题是我想在User模型上加

更新(解决方案)

  • 如果您需要
    ->user
    中的
    $image
    关系,则
    $user
    变量已经可用,因为您从中加载了
    ->images
  • 不要将
    受保护的$与
    雄辩的属性一起使用。这是一种反模式
  • 相反,在需要的位置/时间,显式地按需加载关系(注意:这不应阻止您保持干燥!)
  • 如果您确实需要/想要,请参阅@nicksonyap-answer。它起到了作用(我相信——未经测试)
原创

我遇到了一个我认为很简单的问题:

  • 我有一个
    用户
    对象,它有许多
    图像
    s
  • 图像
    属于
    用户
    。。。(逆关系)
我的问题是我想在
User
模型上加载
images()
,在
images
模型上加载
User()
。为此,我只需设置一个
$with
属性,如文档中所述

我的
用户
型号:

类用户扩展了EloquentModel{
受保护的$with=['images'];
公共功能图像()
{
返回$this->hasMany(Image::class);
}
}
我的
图像
型号:

类图像扩展了EloquentModel{
受保护的$with=['user'];
公共函数用户()
{
返回$this->belongsTo(用户::类);
}
}
但在表演时:

$user=user::find(203);
这将导致无限循环(php分段错误)。一定有某种循环引用,我无法找到:

[1]    85728 segmentation fault
编辑2016/02

这是我发现的最简单的“变通方法”:

//User.php
公共函数setRelation($relation,$value)
{
如果($relation=='images'){
foreach($image的值){
$image->setUser($this);
}
}
返回父::setRelation($relation,$value);
}

当您尝试查找属性时,该属性将立即加载其拥有的所有图像,而每个图像将立即加载其所属的属性,即您尝试查找的属性,该属性将再次开始立即加载其拥有的所有图像。等等

我解决这个问题的方法不是在模型内部进行即时加载,而是在调用模型时进行即时加载

因此,使用以下方法:

$prop = Property::with('images')->find(203);
在属性模型中删除此行时:

protected $with = ['images'];
图像模型中的这一行:

protected $with = ['property'];
我希望此解决方案适合您。

有一种
不带()
的方法:

在关系的两侧放置
而不使用()
有效

类属性扩展了EloquentModel{
受保护的$with=['images'];
公共功能图像()
{
返回$this->hasMany(Image::class)->不带('property');
}
}
类图像扩展了EloquentModel{
受保护的$with=['property'];
公共功能属性()
{
返回$this->belongsTo(属性::类)->不带('images');
}
公共函数getAlt()
{
返回$this->property->title;
}
}
更新:

尽管使用
without()
很容易避免无限循环问题,但通过多年使用Laravel的经验,我意识到在模型中设置
$with
是一种不好的做法,因为它会导致始终加载关系。因此导致循环引用/无限循环

相反,总是使用
with()
来明确指定要立即加载的必要关系,无论多么深入(关系的关系)

例如:

$user=user::with('images'=>函数($query){
$query->with('property'=>函数($query){
$query->with('deeperifneed'=>函数($query){
//...
});
});
]);

注意:可能需要删除
而不使用()

嗨,thx。我感觉到你,我只是很惊讶没有内置的方法来雄辩地处理这种情况。根据我的理解,这就像
属性
接收
图像
关系一样简单,然后对于每个图像
->设置关系('Property',$this)
。我没有向ORM等重新询问相同的属性。我很惊讶没有任何东西阻止你避免可能工作的无限循环(错误消息???)。我接受了你的答案(~3年后…),尽管我建议不要这样做,而是要明确(见我的更新)。