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年后…),尽管我建议不要这样做,而是要明确(见我的更新)。