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

Laravel/Eloquent关联术语及类属性含义咨询

Laravel Eloquent 关联速查表&术语解析

核心术语澄清

先理清几个易混淆的术语:

  • Parent Model(父模型):关联的发起方,关联字段存储在另一方模型中。比如 User hasOne Phone,User 就是父模型。
  • Child Model(子模型):依赖父模型的模型,关联字段(如 user_id)存在于该模型内。比如上面的 Phone。
  • Related Model(关联模型):当前模型要关联的目标模型。比如在 User 的 phone() 方法里,Related 是 Phone;在 Phone 的 user() 方法里,Related 是 User。

各关联类型示例&属性取值

所有示例基于常见业务场景,属性取值为默认规则,自定义字段可手动指定。

1. 一对一关联(hasOne ↔ belongsTo)

场景:一个用户(User)对应一部手机(Phone),一部手机属于一个用户。

User 模型(hasOne)

// app/Models/User.php
public function phone()
{
    return $this->hasOne(Phone::class);
}

hasOne 关联属性取值:

  • $parent:当前 User 实例(如 User::find(1) 返回的对象)
  • $related:Phone 模型类
  • $foreignKey:默认 user_id(父模型蛇形命名 + _id)
  • $localKey:父模型主键,默认 id

Phone 模型(belongsTo)

// app/Models/Phone.php
public function user()
{
    return $this->belongsTo(User::class);
}

belongsTo 关联属性取值:

  • $parent:User 模型类
  • $related:当前 Phone 实例(如 Phone::find(1) 返回的对象)
  • $child:Phone 模型类
  • $foreignKey:当前模型的关联字段,默认 user_id
  • $ownerKey:父模型主键,默认 id

说明:关联字段 user_id 存储在 Phone 表中,hasOne 从父模型找子模型,belongsTo 从子模型找父模型。


2. 一对多关联(hasMany ↔ belongsTo)

场景:一个用户(User)有多篇文章(Post),一篇文章属于一个用户。

User 模型(hasMany)

// app/Models/User.php
public function posts()
{
    return $this->hasMany(Post::class);
}

hasMany 关联属性取值:

  • $parent:当前 User 实例
  • $related:Post 模型类
  • $foreignKey:默认 user_id
  • $localKey:默认 id

Post 模型(belongsTo)

// app/Models/Post.php
public function user()
{
    return $this->belongsTo(User::class);
}

belongsTo 属性取值同一对一场景,$foreignKey 是 Post 表的 user_id,$ownerKey 是 User 表的 id。

说明:hasMany 返回多个关联模型的集合,关联字段存储在子模型(Post)中。


3. 多对多关联(belongsToMany ↔ belongsToMany)

场景:一个用户(User)可拥有多个角色(Role),一个角色可被多个用户拥有,中间表为 user_role(含 user_id、role_id)。

User 模型(belongsToMany)

// app/Models/User.php
public function roles()
{
    return $this->belongsToMany(Role::class);
}

belongsToMany 关联属性取值:

  • $parent:当前 User 实例
  • $related:Role 模型类
  • $foreignKey:当前模型在中间表的字段,默认 user_id
  • $relatedKey:关联模型在中间表的字段,默认 role_id
  • $table:中间表名,默认按两个模型蛇形命名的字母顺序拼接,此处为 user_role

Role 模型(belongsToMany)

// app/Models/Role.php
public function users()
{
    return $this->belongsToMany(User::class);
}

属性取值:

  • $parent:当前 Role 实例
  • $related:User 模型类
  • $foreignKey:role_id
  • $relatedKey:user_id
  • $table:user_role

说明:多对多通过中间表建立关联,两个模型无严格父/子区分,取决于关联发起方。


4. 跨层一对多关联(hasManyThrough)

场景:一个国家(Country)有多个用户(User),一个用户有多个订单(Order),需通过用户关联获取国家的所有订单。

Country 模型(hasManyThrough)

// app/Models/Country.php
public function orders()
{
    return $this->hasManyThrough(Order::class, User::class);
}

hasManyThrough 关联属性取值:

  • $parent:当前 Country 实例
  • $related:Order 模型类
  • $through:中间模型 User 类
  • $firstKey:Country 在 User 表的关联字段,默认 country_id
  • $secondKey:User 在 Order 表的关联字段,默认 user_id
  • $localKey:Country 主键,默认 id

说明:跨两层模型关联,直接从顶层模型(Country)获取底层模型(Order)的数据。


5. 多态一对一关联(morphOne ↔ morphTo)

场景:用户(User)和文章(Post)都可拥有一个头像(Avatar),头像属于某个具体模型。

Avatar 模型(morphTo)

// app/Models/Avatar.php
public function imageable()
{
    return $this->morphTo();
}

morphTo 关联属性取值:

  • $parent:当前 Avatar 实例
  • $related:关联的目标模型(可能是 User 或 Post)
  • $foreignKey:默认 imageable_id
  • $morphType:默认 imageable_type(存储关联模型的类名,如 App\Models\User)

User 模型(morphOne)

// app/Models/User.php
public function avatar()
{
    return $this->morphOne(Avatar::class, 'imageable');
}

morphOne 关联属性取值:

  • $parent:当前 User 实例
  • $related:Avatar 模型类
  • $foreignKey:imageable_id
  • $localKey:User 主键 id
  • $morphType:imageable_type

Post 模型(morphOne)

// app/Models/Post.php
public function avatar()
{
    return $this->morphOne(Avatar::class, 'imageable');
}

说明:多态关联让一个模型同时关联多个不同类型的模型,通过 _id 和 _type 两个字段区分关联目标。


6. 多态一对多关联(morphMany ↔ morphTo)

场景:用户(User)和文章(Post)都可拥有多个评论(Comment)。

Comment 模型(morphTo)

// app/Models/Comment.php
public function commentable()
{
    return $this->morphTo();
}

User 模型(morphMany)

// app/Models/User.php
public function comments()
{
    return $this->morphMany(Comment::class, 'commentable');
}

Post 模型(morphMany)

// app/Models/Post.php
public function comments()
{
    return $this->morphMany(Comment::class, 'commentable');
}

说明:与多态一对一致命区别是,morphMany 返回多个关联模型的集合,属性规则和 morphOne 一致。


7. 多态多对多关联(morphToMany ↔ morphedByMany)

场景:用户(User)和文章(Post)都可被多个标签(Tag)标记,一个标签可关联多个用户或文章。

User 模型(morphToMany)

// app/Models/User.php
public function tags()
{
    return $this->morphToMany(Tag::class, 'taggable');
}

Post 模型(morphToMany)

// app/Models/Post.php
public function tags()
{
    return $this->morphToMany(Tag::class, 'taggable');
}

Tag 模型(morphedByMany)

// app/Models/Tag.php
public function users()
{
    return $this->morphedByMany(User::class, 'taggable');
}

public function posts()
{
    return $this->morphedByMany(Post::class, 'taggable');
}

说明:中间表默认是 taggable_tag,包含 taggable_id、taggable_type、tag_id 三个字段,用来关联不同类型的模型和标签。


内容的提问来源于stack exchange,提问作者Kevin Wheeler

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 20:25:23