- 远程一对一
一个帖子属于一个作者,该作者就读一所学校。帖子可通过作者访问作者所在的学校
模型关系
# App\Thread
public function authorSchool()
{
return $this->hasOneThrough('App\School', 'App\Author');
}
# App\Thread
public function authorSchool()
{
return $this->hasOneThrough(
'App\School',
'App\Author',
'thread_id', // 作者表外键
'author_id', // 学校表外键
'id', // 帖子本地键
'id', // 作者本地键
);
}
查
$school = \App\Thread::find(2)->authorSchool;
$threadsWithSchool = \App\Thread::with('authorSchool')->get();
- 远程一对多
一个帖子属于一个作者,该作者有多本书。帖子可通过作者访问作者的书
模型
# App\Thread
public function authorBook()
{
return $this->hasManyThrough('App\Book', 'App\Author');
}
# App\Thread
public function authorBooks()
{
return $this->hasOneThrough(
'App\Book',
'App\Author',
'thread_id', // 作者表外键
'author_id', // 书表外键
'id', // 帖子本地键
'id', // 作者本地键
);
}
查
$books = \App\Thread::find(2)->authorBooks;
$threadsWithBooks = \App\Thread::with('authorBooks')->get();
- 多态一对一
运营人员就一个图片,发布一篇博客或者一篇文章。
表结构
articles
id - integer
title - string
blogs
id - integer
title - string
images
id - integer
url - string
imageable_id - integer
imageable_type - string
模型
# App\Image,imageable和表字段名对应
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\Blog::create(['title'=>'test'])->image()->create(['url'=>'123465'])
查
$article = App\Article::find(1);
$image= $article->image;
$articleWithImages = App\Article::with('image')->find(1);
$articlesWithImages = App\Article::with('image')->find([1, 2]);
App\Image::with('imageable')->get()->toArray();
$image = App\Image::find(1);
$imageable = $image->imageable;
- 多态一对多
文章可以接受多条评论,视频也可以接受多条评论。
表
articles
id - integer
title - string
body - text
videos
id - integer
title - string
url - string
comments
id - integer
body - text
commentable_id - integer
commentable_type - string
模型结构
# 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');
}
- 多态多对多
表
articles
id - integer
name - string
videos
id - integer
name - string
tags
id - integer
name - string
taggables
tag_id - integer
taggable_id - integer
taggable_type - string
模型
# 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');
}
查
$video = App\Video::find(1);
foreach ($video->tags as $tag) {
//
}
$tag = App\Tag::find(1);
foreach ($tag->videos as $video) {
//
}
$videoWithTags = App\Video::with('tags')->find(1);
$videosWithTags = App\Video::with('tags')->find([1, 2]);
$tagWithVideos = App\Tag::with('videos')->find(1);
$tagsWithVideos = App\Tag::with('videos')->find([1, 2]);
定制
# app/Providers/AppServiceProvider.php 的boot中
use Illuminate\Database\Eloquent\Relations\Relation;
Relation::morphMap([
'posts' => 'App\Post', // posts 是 *_type 字段所存储的值
'videos' => 'App\Video',
]);