Laravel学习笔记基础系列--(二十六)Laravel 模型之间的关联关系
作者:温新
时间: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');
}
关于基础的 一对一、一对多、多对多关联关系就记录到这里了。关联关系中最复杂最难以理解的就是多对多的关联关系,因此,需要多多练习。
对于参数的省略问题,建议把参数写全,便于理解与记忆。当对关联关系了然于胸时再省略也不迟。好了,基础的关联关系就记录到这里了。我是温新,欢迎和大家一起交流学习。
我是温新
每天进步一点点,就一点点