模型关联使用总结

一对一

$this->hasOne(关联模型的类名, 关联模型的外键, 当前模型的主键);

如(用户拥有的那个手机):

public function phone()
{
     return $this->hasOne(Phone::class, 'user_id', 'id');
}

反向关联
文档中提到的父级对象模型=这里的关联模型

$this->belongsTo(关联模型的类名, 当前模型的外键, 关联模型的主键);

如(拥有这个手机的用户):

public function user()
{
     return $this->belongsTo(User::class, 'user_id', 'id');
}

一对多
模型方法参数和一对一一致

$this->hasMany(关联模型的类名, 关联模型的外键, 当前模型主键);

如(一篇文章拥有多次评论):

public function comments()
{
     return $this->hasMany(Comment::class, 'article_id', 'id');
}

多对多

$this->belongsToMany(关联的模型类名, 中间表表名, 
    当前模型在中间模型中的外键名称, 关联模型在中间模型的外键名称);

如(用户拥有的所有角色):

public function roles() {
    return $this->belongsToMany(Role::class, 'role_user', 'user_id', 'role_id');
}

远层一对多

$this->hasManyThrough(
    最终访问的模型类名, 中间模型的类名,
    中间模型的外键名称, 最终模型的外键名称, 当前模型的主键
);

如(一个国家有很多用户,用户又可以发布多篇文章,获取某国家所有用户发布的多有文章):

public function articles() {
    return $this->hasManyThrough(Article::class, User::class, 'country_id', 'user_id', 'id');
}

多态关联

$this->morphMany(中间模型类名, 
    中间表来源字段前缀, 中间模型类型字段,
    中间模型来源字段, 当前模型的主键);

如(文章和用户都可以别点赞,根据点赞记录Follow获取来源):

aticles
    id - integer
    title - string
 users
    id - integer
    name - string
follows
    id - integer
    source_id - integer
    source_type - string
class Follow extends Model
{
    // 方式一
    public function source()
    {
        return $this->morphTo(); // 中间表前缀会使用模型方法名source,得到中间表类型字段source_type和中间表来源字段source_id
    }
    // 方式二
    public function comment()
    {
        return $this->morphTo('source'); // 即使模型方法名不正确,可以使用正确的中间表前缀source,同样得到正确结果
        // 和以下方式结果一致
        // return $this->morphTo('comment', 'source_type', 'source_id'); // 即使中间表前缀名称不正确,只要指定正确的中间表类型字段和中间表来源字段,同样可以得到正确的结果
    }
}

主键、外键

定义主键和外键主要是为了维护关系数据库的完整性,总结一下:
1.主键是能确定一条记录的唯一标识,比如,一条记录包括身份证号,姓名,年龄。
身份证号是唯一能确定你这个人的,其他都可能有重复,所以,身份证号是主键。
2.外键用于与另一张表的关联。是能确定另一张表记录的字段。
如:id是users的主键,country_id可以确定countries表的一条记录,是users的外键

countries
    id - integer
    name - string
users
    id - integer
    country_id - integer
    name - string
本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 5年前 自动加精
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 14
ThinkQ

不错额。

5年前 评论

多态关联示例写得不对,,,再检查一下,,,,
方案一morphTo少了参数
方案二多写了个return

5年前 评论

@xychenjin 谢谢建议,不过可能你得再看下官方原文档了;方案二我再改一下哈

5年前 评论

工作中不建议用外键

5年前 评论

@brady_wang234 是的,这里有点问题,父级是指所属模型

5年前 评论

通俗易懂,赞一个。

4年前 评论

多态关联时如何指定查询的字段呢? 比如 使用 hasOne时 可以使用select指定, $this->hasOne()->select(), 多态关联时 select 无用, 那我如何取指定字段呢, 并不想查询所有字段

11个月前 评论
haibin_hu (楼主) 11个月前
haibin_hu (楼主) 11个月前
cnian (作者) 11个月前
cnian (作者) 11个月前
haibin_hu (楼主) 11个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!