Laravel学习笔记基础系列--(二十六)Laravel 模型之间的关联关系

作者: 温新

分类: 【Laravel】

阅读: 2018

时间: 2021-07-27 15:10:47

作者:温新

时间:2021-07-01

一个作者可以有多篇文章,一般情况下用的最多的是关联查询。当用了关联关系会,你会爱上她。少量代码就实现了关联之间的数据查询。

准备工作

我们已经有了users表与posts,这是一个一对多的关系,因此我们建立一个用户档案表,与users表是一对一关系。

// 1、创建模型并生成迁移文件
php artisan make:model UserProfile -m
// 2、迁移文件
Schema::create('user_profiles', function (Blueprint $table) {
    $table->id();
    $table->integer('user_id')->unsigned()->default(1)->unique();
    $table->string('id_card')->nullable()->comment('身份证');
    $table->timestamps();
});
// 3、php artisan migrate --path=database/migrations/2021_06_30_172431_create_user_profiles_table.php
// 4、填充数据,自行执行

一对一关联查询

hasOne正向关联

方法:hasOne($className,$foreignKey=null,$localKey=null

案例:hasOne('App\Models\UserProfile','user_id','id')

参数解释:

return $this->hasOne($className,$foreignKey=null,$localKey=null);

参数一:要关联的模型类名。               这里指 UserProfile模型
参数二:要关联模型所属表中的外键。       这里指 user_profiles表中的user_id
参数三:关联表的外键。                 这里指 users表中的id

hasOne要关联模型名所对应表的外键与关联表的主键关键

案例:通过用户获取其档案信息

第一步:定义模型关联

位置:app/Models/User.php

// 推荐把参数写全
public function userProfile()
{
    return $this->hasOne(UserProfile::class, 'user_id', 'id');
}

第二步:控制器使用

文件:DemoController.php

public function demo()
{
    // 先获取用户信息,然再获取档案信息
    $user = \App\Models\User::find(1)->userProfile;
    return view('demo.demo');
}

控制器中调用时,是User模型中的userProfile方法当作一个动态属性来调用。

belongsTo反向关联

方法:belongsTo($className, $foreignKey = null, $ownerKey = null, $relation = null)

参数一:关联模型文件。如 User

参数二:当前模型外键,如UserProfile模型的外键user_id

参数三:关键模型住建,如User模型的id

第一步:定义模型方法

文件:app/Models/UserProfile.php

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

**第二步:控制器调用 **

文件:DemoController.php

use App\Models\UserProfile;
public function demo()
{
    $userProfile = UserProfile::find(1)->user;
    return view('demo.demo');
}

一对多关联

一对多,如一个作者可以发布很多文章,再如一篇文章有N多评论,这都形成了一个一对多的关系。

hasMany正向关联

方法:hasMany($related, $foreignKey = null, $localKey = null)

参数一:关联模型,如关键Post模型;

参数二:关键外键ID,如 Post模型中的user_id;

参数三:本模型主键,如User模型的id

第一步:定义模型方法

文件:app/Models/User.php

public function posts()
{
    return $this->hasMany(Post::class,'user_id','id');
}

第二步:控制器调用

文件:DemoController.php

$userPosts = User::find(1)->posts;

belongsTo反向关联

一个可以有多篇文章,那么返过来就是多篇文章属于某一个作者,也就是可以通过文章来反查作者信息。

方法:belongsTo($related, $foreignKey = null, $ownerKey = null, $relation = null)

参数一:关联模型,如User模型;

参数二:关键模型外键,如Post表中的user_id;

参数三:主键ID

第一步:定义模型方法

文件:app/Models/Post.php

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

第二步:控制器调用

文件:DemoController.php

public function demo()
{
    $posts = Post::with('userInfo')->where('user_id',1)->get();
    return view('demo.demo', compact('posts'));
}

获取文章信息时,可以通过with方法并传入动态关联属性名(也就是方法)就可以一次完成动态关联查询。

这里可以dd($posts)来看看,除了所有文章被查了出来之外,每个模型对象里面包有一个relations属性,其中就有关联作者信息的userInfo数组,这里面就包含了作者信息。

第三步:视图使用

文件:demo.blade.php

@foreach($posts as $post)
{{--文章标题--}}
{{$post->title}}
{{--    作者名称--}}
{{$post->userInfo->name}}
@endforeach

多对多关联

一篇文件可以有多个标签,一个标签可能有属于多篇文章,那么,文章和标签之间就属于多对对的关系。要实现多对对关系就必须借助中间表来实现,为此我们需要创建一个中间表与标签表。

准备工作

创建Tag标签表

第一步:创建标签模型与迁移文件

php artisan make:model Tag -m

第二步:编写迁移文件

Schema::create('tags', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name', 100)->unique()->comment('标签名');
    $table->timestamps();
});

第三步:创建中间表post_tags迁移文件

php artisan make:migration create_post_tags_table --create=post_tags

第四步:编写迁移文件

Schema::create('post_tags', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('post_id')->unsigned()->default(1);
    $table->integer('tag_id')->unsigned()->default(1);
    $table->unique(['post_id', 'tag_id']);
    $table->timestamps();
});

第五步:执行迁移

php artisan migrate --path=database/migrations/2021_07_01_150103_create_tags_table.php
php artisan migrate --path=database/migrations/2021_07_01_150504_create_post_tags_table.php

第六步:关于数据,请自行填充

belongsToMany正向关联

方法:belongsToMany($related, $table = null, $foreignPivotKey = null, $relatedPivotKey = null,$parentKey = null, $relatedKey = null, $relation = null)

暂时只用到前四个参数,因此只说前四个参数。

参数一:关联模型。这里是Tag模型;

参数二:中间表名,这里是post_tag中间表;

参数三:中间表关联外键ID,post_tag中间表的post_id;

参数四:中间表关联外键ID,post_tag中间表的tag_id;

参数五:当前模型的字段,默认Post模型的主键id;

参数六:关联模型的哪个字段,默认Tag模型的主键ID;

参数七:关联关系名称,默认是关联关系方法名

**案例:**获取一篇文章的所有标签

第一步:定义模型方法

文件:`app/Models/Post.php

public function tags()
{
    return $this->belongsToMany(Tag::class,'post_tags','post_id','tag_id','id','id');
}

第二步:控制器调用

文件:DemoController.php中的demo方法

$post = Post::with('tags')->find(1);

belongsToMany反向关联

由于多对多关联关系之间是平等的,因此建立相对关联关系的方法是一样的。

**案例:**查找标签下的所有文章

第一步:定义模型关联

文件:app/Models/Tag.php

public function posts()
{
    return $this->belongsToMany(Post::class,'post_tags','post_id','tag_id','id','id');
}

第二步:控制器调用

文件:DemoController.php中的demo方法

public function demo()
{
    $tags = Tag::with('posts')->where('name','Laravel')->first();
    dd($tags);
    return view('demo.demo');
}

关于基础的 一对一、一对多、多对多关联关系就记录到这里了。关联关系中最复杂最难以理解的就是多对多的关联关系,因此,需要多多练习。

对于参数的省略问题,建议把参数写全,便于理解与记忆。当对关联关系了然于胸时再省略也不迟。好了,基础的关联关系就记录到这里了。我是温新,欢迎和大家一起交流学习。

我是温新

每天进步一点点,就一点点

请登录后再评论