Laravel一对一关联查询返回父模型重复问题咨询
问题:Laravel一对一关联中,Property模型返回结果包含重复的User数据
我定义了两个Laravel模型并建立了一对一关联:
class Property extends Model { public function user() { return $this->belongsTo(User::class, 'user_id'); } } class User extends Authenticatable { public function property() { return $this->hasOne(Property::class, 'user_id'); } }
当我通过Property模型获取关联的User时,返回结果中出现了两次User数据:
$property = Property::where('id', $id)->first(); return response()->json([ 'property' => $property, 'user' => $property->user ], 201);
输出结果:
{ "property":{ "id":1, "name":"test", "user":{ "id":1, "name":"arash" } }, "user":{ "id":1, "name":"arash" } }
请问这是什么原因?为何Property对象中也包含了User数据?
回答
这是Laravel的**懒加载(Lazy Loading)**特性导致的,当你第一次访问$property->user的时候,Laravel会自动执行SQL查询获取关联的User数据,并且会把这个加载后的User实例附加到$property模型的属性中。当你将$property转换为JSON响应时,Laravel会自动将所有已加载的关联关系也序列化进去,所以就出现了重复的User数据。
解决这个问题很简单,你只需要在返回$property的时候,临时隐藏掉它的user关联属性即可,使用makeHidden方法:
$property = Property::where('id', $id)->first(); return response()->json([ 'property' => $property->makeHidden('user'), 'user' => $property->user ], 201);
这样输出的JSON里,property对象就不会包含user字段,只会在单独的user字段里返回一次用户数据。
另外补充两种可选方案:
- 如果你想全局隐藏这个关联,可以在
Property模型里添加$hidden属性:protected $hidden = ['user'];,但这样所有返回Property模型的场景都会隐藏user关联,需要根据你的业务需求判断是否适用。 - 也可以使用
with预加载关联,然后同样用makeHidden处理,效果是一样的:
$property = Property::with('user')->where('id', $id)->first(); return response()->json([ 'property' => $property->makeHidden('user'), 'user' => $property->user ], 201);
内容的提问来源于stack exchange,提问作者Arash Hatami
相关产品推荐
相关产品推荐

