Laravel学习笔记(七)---操作数据库--Eloquent ORM--关联关系及其在模型中的定义

关联关系及其在模型中的定义

用户表:users
社交账号表:user_accounts
文章表:posts
角色表:roles
中间表:role_user(用于记录users表与roles表的对应关系)
国家表:countries
视频表:videos
评论表:comments
标签表:tags
关系表:taggables(该表中定义了文章/视频与标签的对应关系。)

1、一对一

一对一是最简单的关联关系,表示表A和表B的记录一一对应,比如一个用户对应一个社交账号,在演示该关联关系之前我们先创建一个社交账号表user_accounts
接下来我们开始在User中定义与UserAccount的一对一对应关系:
public function account()
{
    return $this->hasOne('App\Models\UserAccount');
}
相对的,我们也可以在UserAccount模型中定义与User的一对一关系:

public function user()
{
    return $this->belongsTo('App\User');
}
2、一对多

一对多是一种常见的关联关系,用于表示表A的某条记录对应表B的多条记录,反之表B的某条记录归属于表A的某条记录,比如一个用户发表多篇文章,定义一对多的关系也很简单,我们在用户模型User中定义与文章模型Post的一对多关系如下:

public function posts()
{
    return $this->hasMany('App\Models\Post');
}
同样,我们可以在文章模型Post中定义文章所属用户模型User的对应关系:

public function author()
{
    return $this->belongsTo('App\User','user_id','id');
}
3、多对多

另外一种常见的关联关系是多对多,即表A的某条记录通过中间表C与表B的多条记录关联,反之亦然。比如一个用户有多种角色,反之一个角色对应多个用户。

在User中定义多对多关联如下:

public function roles()
{
    return $this->belongsToMany('App\Models\Role');
}
也可以在模型Role中定义获取对应User模型的方法:

public function users()
{
    return $this->belongsToMany('App\User');
}
4、远层一对多

所谓的“远层一对多”指的是通过一个中间关联对象访问远层的关联关系,比如用户与文章之间存在一对多关系,国家与用户之间也存在一对多关系,那么通过用户可以建立国家与文章的之间的一对多关联关系,我们称之为“远层一对多”。

为了测试该关联关系我们新建一个国家表countries并初始化两条记录
我们创建一个模型类Country,并在其中定义国家与文章的远层一对多关系如下:

public function posts()
{
    return $this->hasManyThrough('App\Models\Post','App\User');//countries表通过远程表users表关联posts表
}
5、多态关联

顾名思义,多态关联允许一个模型在单个关联下属于多个不同父模型。常见的多态关联就是评论,这里需要引入一个新的节点类型——视频,现在我们的内容类型包括文章和视频,用户既可以评论文章 ,也可以评论视频 。
文章存在文章表posts,视频存在视频表videos,评论存在评论表comments,某一条评论可能归属于某篇文章,也可能归属于某个视频,那么问题来了,如何定义这种关联关系呢?
答案是多态关联:我们可以在评论表中添加一个item_id字段表示其归属节点ID,同时定义一个item_type字段表示其归属节点类型,这样就可以完美解决评论所属问题。
首先在Post和Video模型类中定义关联评论如下:

public function comments()
{
    return $this->morphMany('App\Models\Comment','item');
}
6、多对多多态关联

多态关联之后还有一个更加复杂的关联——多对多的多态关联,这种关联最常见的应用场景就是标签,比如一篇文章对应多个标签,一个视频也对应多个标签,同时一个标签可能对应多篇文章或多个视频,这就是所谓的“多对多多态关联”。
此时仅仅在标签表tags上定义一个item_id和item_type已经不够了,因为这个标签可能对应多个文章或视频,那么如何建立关联关系呢,我们可以通过一张中间表taggables来实现:该表中定义了文章/视频与标签的对应关系。
然后创建模型类Tag和Taggable,并在Post/Video中定义关联关系如下:

public function tags()
{
    return $this->morphToMany('App\Models\Tag','taggable');
}
在Tag中定义相对的关联关系如下:

public function posts()
{
    return $this->morphedByMany('App\Models\Post','taggable');
}

public function videos()
{
    return $this->morphedByMany('App\Models\Video','taggable');
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值