博客
关于我
laravel 5.5 -- Eloquent 模型关联
阅读量:793 次
发布时间:2023-01-30

本文共 3933 字,大约阅读时间需要 13 分钟。

Laravel 6 模型关系精讲

一对一关系

正向关联

在 Laravel 中,一对一关系(One-to-One)是非常常见的关联类型,适用于一个用户拥有唯一的手机号码这种情况。我们可以通过 hasOne 方法来定义这样的关系。

  • 定义关联

    User 模型中添加如下方法:

    public function phone(){    return $this->hasOne('App\Phone');}public function phone(){    // 如果你想要自定义外键名称,可以传第二个参数    return $this->hasOne('App\Phone', 'foreign_key');public function phone(){    // Eloquent 会根据模型的 `primaryKey` 假设外键字段的名称。如果需要自定义,可以传第三个参数    return $this->hasOne('App\Phone', 'foreign_key', 'local_key');}
  • 使用方法

    $user = User::find(1);$phone = $user->phone; // 获取用户关联的手机号

    如果 Phone 模型没有找到对应的记录,则会返回 null

  • 关联,默认模型

    可以使用 withDefault 方法,为关联关系提供一个默认的模型实例:

    return $this->hasOne('App\Phone')->withDefault();

    或者,如果你需要为默认模型补充额外的数据:

    return $this->hasOne('App\Phone')->withDefault([    'name' => '游客']);

反向关联

在涉及一对一关系的子模型中,你需要定义一个 belongsTo 关联。例如,在 Phone 模型中,告诉 Eloquent 上级模型是 User

public function user(){    return $this->belongsTo('App\User');}

使用方法相同,可以直接通过关联获取用户的信息。

$phone = Phone::find(1);$user = $phone->user;

一对多关系

一对多关系(One-to-Many)常用于类似博客文章与评论的场景。一个博客文章可能有多个评论。

正向关联

Post 模型中定义 comments 关联:

public function comments(){    return $this->hasMany('App\Comment');}
  • 使用方法

    $post = Post::find(1);$comments = $post->comments;

    如果你想对评论进行筛选,可以在关系上附加条件:

    $comments = Post::find(1)    ->comments()    ->where('title', 'foo')    ->first();
  • 反向关联

    Comment 模型中定义:

    public function post(){    return $this->belongsTo('App\Post');}

关联默认模型

如果你需要为反向关联提供一个默认的模型,可以使用 withDefault 方法:

return $this->belongsTo('App\Post')->withDefault();

多对多关系

多对多(Many-to-Many)关系通常用于一个用户拥有的多个角色,而一个角色可以被多个用户拥有。这种关系需要一个中间表(Intermediate Table),一般命名为字母顺序结合两个模型的命名,例如 role_user

正向关联

User 模型中定义:

public function roles(){    return $this->belongsToMany('App\Role');}

反向关联

Role 模型中定义:

public function users(){    return $this->belongsToMany('App\User');}

多态关联

多态关联(Polymorphic Relations)允许一个模型同时关联到不同的模型类型,比如一个评论可以关联到文章或视频。

数据库设计

通常会有以下表结构:

表名 id title ...
posts id title ...
videos id title ...
comments id body commentable_id commentable_type

Comment 模型中定义:

public function commentable(){    return $this->morphTo();}

PostVideo 模型中定义:

public function comments(){    return $this->morphMany('App\Comment', 'commentable');}

使用方法

$comment = Comment::find(1);$commentable = $comment->commentable;

如果 $commentablePost 类型,你可以继续调用其它方法。

自定义多态关联类型字段

如果中间表需要额外的字段,可以通过 using 方法定义自定义关联类:

public function users(){    return $this->belongsToMany('App\User')->using('App\UserRole');}

多对多关联

多对多(Many-to-Many)关系适用于多个模型通过中间表关联。例如,博客的 PostVideo 可以共享 Tag 的关联。

数据库设计

表名 id name
posts id name
videos id name
tags id name
taggables tag_id taggable_id taggable_type

Post 模型中定义:

public function tags(){    return $this->morphToMany('App\Tag', 'taggable');}

Tag 模型中定义:

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

关联数据计数

如果你需要统计关联数据,可以使用 withCount 方法:

$posts = App\Post::withCount('comments')->get();

这样会在结果中添加 comments_count 字段。


遥层关联(Has Many Through)

Country 模型关联多个 Post 模型,可以通过中间的 User 模型:

public function posts(){    return $this->hasManyThrough('App\Post', 'App\User');}

延迟预加载

你可以在需要时懒加载关联:

$books = App\Book::all();if ($someCondition) {    $books->load('author', 'publisher');}

插入与更新关联模型

  • 保存

    $comment = new Comment(['message' => 'A new comment.']);$post = Post::find(1);$post->comments()->save($comment);
  • 保存多条

    $post = Post::find(1);$post->comments()->saveMany([    new Comment(['message' => 'A new comment.']),    new Comment(['message' => 'Another comment.'])]);
  • 创建

    $post = Post::find(1);$comment = $post->comments()->create(['message' => 'A new comment.']);

多对多关联操作

  • 附加

    $user = User::find(1);$user->roles()->attach($roleId);
  • 移除

    $user->roles()->detach($roleId);
  • 更新

    $user->roles()->save($role, ['expires' => $expires]);

连动父级时间戳

Comment 模型中定义:

protected $touches = ['post'];public function post(){    return $this->belongsTo('App\Post');}

这样,当一个 Comment 被保存或更新时,父级 Postupdated_at 时间戳会被自动更新。

转载地址:http://ekgyk.baihongyu.com/

你可能感兴趣的文章
Kubernetes网络插件使用详解
查看>>
kubernetes调度pod运行于master节点上
查看>>
Kubernetes调度单位Pod
查看>>
Kubernetes部署Dashboard实战
查看>>
kubernetes部署nacos2.3.0
查看>>
Kubernetes集群升级实战
查看>>
kubernetes集群添加到jumpserver堡垒机里管理
查看>>
KubeSphere核心实战_kubesphere部署redis02_创建redis现指定存储卷_配置外网访问服务---分布式云原生部署架构搭建048
查看>>
KuiperInfer深度学习推理框架-源码阅读和二次开发(3):计算图
查看>>
KVM 安全策略配置实战
查看>>
KVM 性能测试优化实战
查看>>
KVM命令行管理企业级实战
查看>>
KVM迁移与维护实战
查看>>
KxMenu下拉菜单
查看>>
KXML2部分详解(J2ME)
查看>>
KXML解释本地或网络上的XML文件
查看>>
Kylin学习笔记 - CDH6.2集群 kylin2.6.4 环境搭建
查看>>
Kylin学习笔记 - 使用Java模拟生成测试数据
查看>>
Kylin踩坑笔记 - /developer/apache-kylin-2.6.2-bin/tomcat/conf/.keystore (No such file)
查看>>
labview如何加载库_LabVIEW中调用DLL文件实现温湿度数据显示(VI源码+驱动库+图片说明)...
查看>>