You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel中使用Eloquent获取三级关联关系的数据?

从User模型直接获取密钥数据的实现方案

现有数据表与模型关联

用户表(每个用户对应唯一手机号)

idNamephone_id
1Sam1
2Tom2

对应的User模型代码:

/**
* @return HasOne
*/
public function phone()
{
    return $this->hasOne(phones::class);
}

/**
* @return ???
*/
public function key()
{
    return ???;
}

手机号表(每个手机号对应唯一密钥)

idNamekey_id
1Nokia1
2Samsung2

对应的Phones模型代码:

/**
* @return HasOne
*/
public function key()
{
    return $this->hasOne(keys::class);
}

密钥表

idName
1asd123
2qwe345

对应的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 06:50:26