如何在Laravel中使用Eloquent获取三级关联关系的数据?
从User模型直接获取密钥数据的实现方案
现有数据表与模型关联
用户表(每个用户对应唯一手机号)
| id | Name | phone_id |
|---|---|---|
| 1 | Sam | 1 |
| 2 | Tom | 2 |
对应的User模型代码:
/** * @return HasOne */ public function phone() { return $this->hasOne(phones::class); } /** * @return ??? */ public function key() { return ???; }
手机号表(每个手机号对应唯一密钥)
| id | Name | key_id |
|---|---|---|
| 1 | Nokia | 1 |
| 2 | Samsung | 2 |
对应的Phones模型代码:
/** * @return HasOne */ public function key() { return $this->hasOne(keys::class); }
密钥表
| id | Name |
|---|---|
| 1 | asd123 |
| 2 | qwe345 |
对应的Keys模型代码:
/** * @return belongTo */ public function phone() { return $this->belongTo(phones::class); }
需求
希望实现类似User::find(1)->key->Name的调用,直接从User模型获取密钥数据。
实现方案
第一步:修正关联定义(必要)
当前Phones模型的key()关联定义有误,手机号表通过key_id关联到密钥表的id,属于从属关联,需改为belongsTo:
// Phones模型 /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function key() { return $this->belongsTo(keys::class, 'key_id'); }
第二步:在User模型中添加密钥关联
提供两种实现方式:
方式1:使用hasOneThrough跨表关联
Laravel的hasOneThrough支持跨越中间模型建立直接关联:
// User模型 /** * @return \Illuminate\Database\Eloquent\Relations\HasOneThrough */ public function key() { return $this->hasOneThrough( keys::class, // 最终关联的密钥模型 phones::class, // 中间的手机号模型 'id', // 中间模型Phones与User关联的字段(User的phone_id对应Phones的id) 'id', // 密钥模型keys与中间模型关联的字段(Phones的key_id对应keys的id) 'phone_id', // User模型关联到Phones的外键 'key_id' // Phones模型关联到keys的外键 ); }
定义完成后,直接通过属性访问获取密钥:
// 获取Sam的密钥名称 User::find(1)->key->Name; // 返回 "asd123"
方式2:通过嵌套关联封装
如果不想使用跨表关联,可直接封装嵌套关联的调用:
// User模型 /** * @return keys|null */ public function key() { return $this->phone->key; }
调用方式相同:
User::find(1)->key->Name; // 返回 "asd123"
注:若坚持使用
User::find(1)->key()->Name的写法,方式2的实现可直接满足,因为方法返回的是密钥模型实例而非查询构造器。
内容的提问来源于stack exchange,提问作者buczo
相关产品推荐
相关产品推荐

