Laravel 模型关联:更多使用方法 – 1
复习模型关联
一对一: 一个人只有一个身份证,一个身份证只属于一个人。
// App\User
public function identity_card(){
return $this->hasOne('App\IdentityCard');
}
// App\IdentityCard
public function user(){
return $this->belongsTo('App\User');
}
一对多:一篇文章可以有多个评论,一个评论只属于一篇文章。
// App\Article
public function comments(){
return $this->hasMany('App\Comment');
}
// App\Comment
public function article(){
return $this->belongsTo('App\Article');
}
多对多:一个人可以扮演多个角色,一个角色可以被多个人扮演。
// App\Role
public function users(){
return $this->belongsToMany('App\User');
}
// App\User
public function roles(){
return $this->belongsToMany('App\Role');
}
远程一对一:一个帖子属于一个作者,该作者就读一所学校。帖子可通过作者访问作者所在的学校。
# App\Thread
public function authorSchool()
{
return $this->hasOneThrough('App\School', 'App\Author');
}
远程一对多:一个帖子属于一个作者,该作者写过很多书。帖子可通过作者访问作者写过的所有书籍。
# App\Thread
public function authorBook()
{
return $this->hasManyThrough('App\Book', 'App\Author');
}
多态一对一:运营人员就一个图片,发布一篇博客或者一篇文章。
# App\Image
public function imageable()
{
return $this->morphTo();
}
# App\Blog
public function image()
{
return $this->morphOne('App\Image', 'imageable');
}
# App\Article
public function image()
{
return $this->morphOne('App\Image', 'imageable');
}
多态一对多:文章可以接受多条评论,视频也可以接受多条评论。
# App\Comment
public function commentable()
{
return $this->morphTo();
}
# App\Video
public function comments()
{
return $this->morphMany('App\Comment', 'commentable');
}
# App\Article
public function comments()
{
return $this->morphMany('App\Comment', 'commentable');
}
多态多对多:可以给一篇文章打上多个标签,也可以给一个视频打上多个标签。并且一个标签可以贴在多个文章上面。一个标签也可以贴在多个视频上。
# App\Tag
public function articles()
{
return $this->morphedByMany('App\Article', 'taggable');
}
public function videos()
{
return $this->morphedByMany('App\Video', 'taggable');
}
# App\Article
public function tags()
{
return $this->morphToMany('App\Tag', 'taggable');
}
# App\Video
public function tags()
{
return $this->morphToMany('App\Tag', 'taggable');
}
关系 | 正向 | 反向 |
---|---|---|
一对一 | hasOne | belongsTo |
一对多 | hasMany | belongsTo |
多对多 | belongsToMany | belongsToMany |
远程一对一 | hasOneThrough | — |
远程一对多 | hasManyThrough | — |
多态一对一 | morphTo | morphOne |
多态一对多 | morphTo | morphMany |
多态多对多 | morphedByMany | morphToMany |
一对一、一对多
增
$comment = new App\Comment(['message' => 'A new comment.']);
$post = App\Post::find(1);
$post->comments()->save($comment);
// insert into `comments` (`message`, `post_id`, `updated_at`, `created_at`) values ('A new comment.', 1, '2019-09-19 03:59:48', '2019-09-19 03:59:48')
$post->comments()->saveMany([
new App\Comment(['message' => 'A new comment.']),
new App\Comment(['message' => 'Another comment.']),
]);
$comment = $post->comments()->create([
'message' => 'A new comment.',
]);
// insert into `comments` (`message`, `post_id`, `updated_at`, `created_at`) values (A new comment., 1, 2019-09-19 04:07:43, 2019-09-19 04:07:43)
// 还可以使用 firstOrNew, firstOrCreate 和 updateOrCreate
$post->comments()->createMany([
[
'message' => 'A new comment.',
],
[
'message' => 'Another new comment.',
],
]);
改
$post = App\Post::find(1);
$post->comments[0]->message = 'Message';
$post->comments[0]->name = 'Author Name';
$post->push();
// update `comments` set `message` = Message, `name` = Author Name, `comments`.`updated_at` = 2019-09-19 04:06:09 where `id` = 1
belongsTo
建立模型关系
$user = App\User::find(10);
$comment = App\Comment::find(1);
$comment->user()->associate($user);
$comment->save();
删除模型关系
$comment->account()->dissociate();
$comment->save();
默认模型
# belongsTo, hasOne, hasOneThrough, 和 morphOne
public function user()
{
return $this->belongsTo('App\User')->withDefault();
}
return $this->belongsTo('App\User')->withDefault([
'name' => 'Guest Author',
]);
return $this->belongsTo('App\User')->withDefault(function ($user, $post) {
$user->name = 'Guest Author';
});
belongsTo 或者 belongsToMany
当 Comment 模型被更新时,您要自动「触发」父级 Article 模型的 updated_at 时间戳的更新
protected $touches = ['article'];