Laravel HasOne关联无数据时如何返回空对象而非默认对象
Laravel hasOne关联无匹配数据时返回空对象实现方案
问题场景
两张数据表,主表存储全量业务记录,部分主表记录在关联副表中无对应数据。需求为hasOne关联在无匹配数据时返回空对象{}而非null,直接使用withDefault()方法会返回携带外键字段的对象,不符合预期。
当前实际输出
{ "id": 3, "name": "S", "test": { "test_1_id": 3 } }
期望输出
{ "id": 3, "name": "S", "test": {} }
现有关联代码
public function test(){ return $this->hasOne('\App\TestTwo',"test_1_id","id")->withDefault(); }
约束要求
- 必须查询主表全部记录
- 兼容部分主表记录无副表关联数据的情况
- 无关联数据时关联字段必须返回格式为
{}的空对象
实现方法
withDefault()默认生成的空模型会自动填充关联外键字段维持绑定关系,所以会出现多余的外键属性,通过以下两种方式可以实现返回纯空对象的需求:
方法1:修改withDefault回调清空模型属性
直接在关联定义中,给withDefault()传入闭包,手动清空空模型的所有属性,从根源去掉多余字段:
public function test(){ return $this->hasOne(\App\TestTwo::class, "test_1_id", "id") ->withDefault(function ($emptyModel) { // 清空所有默认填充的属性(包括外键) $emptyModel->setRawAttributes([]); }); }
该方法返回的空关联模型无任何属性,序列化为JSON时会自动转换为标准空对象{},不需要额外处理输出格式。
方法2:序列化阶段处理返回值
如果不想修改关联定义逻辑,可以在模型序列化输出阶段做判断替换:
// 在主表模型中重写jsonSerialize方法 public function jsonSerialize() { $result = parent::jsonSerialize(); // 关联已加载、且关联模型无主键(即为默认空模型)时替换为空对象 if ($this->relationLoaded('test') && !$this->test->exists) { $result['test'] = new \stdClass(); } return $result; }
注意:不要使用空数组代替空对象,空数组
[]序列化为JSON后会输出数组格式,必须使用空模型清空属性或者stdClass实例才能输出正确的{}格式。
内容的提问来源于stack exchange,提问作者Lakhan P
相关产品推荐
相关产品推荐

