1. 一般关联
hasOne、hasMany、hasManyXXX 外键名默认都是“拥有者模型名称加上 _id” belongsTo 外键名默认是"关联方法名加上 _id" belongsToMany 外键1名默认是“拥有者模型名称加上 _id”,外键2名默认是“关联模型单数名称加上 _id” //未确定 ->pivot //多对多关联中的中间表模型,但只可以访问主键,除非在定义关联时明确声明可使用的中间表的哪些字段: ->belongsToMany('...')->withPivot('created_at','updated_at') 2. 多态关联:一个表中有两个字段,一个是其它表的外键,一个是指定哪个其它表。 2.1 如“用户既可以对文章进行评论也可以对视频进行评论”的场景 2.2 表结构 //注意“commentable” ··· posts id - integer title - string body - textvideos
id - integer title - string url - stringcomments
id - integer body - text commentable_id - integer commentable_type - string ··· 2.3 代码形式 //注意“commentable” ··· <?phpnamespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{ /** * Get all of the owning commentable models. */ public function commentable() { return $this->morphTo(); } }class Post extends Model
{ /** * Get all of the post's comments. */ public function comments() { return $this->morphMany('App\Comment', 'commentable'); } }class Video extends Model
{ /** * Get all of the video's comments. */ public function comments() { return $this->morphMany('App\Comment', 'commentable'); } } ··· 2.4 获取多态关联 //Comment 模型的 commentable 关联返回 Post 或 Video 实例,这取决于哪个类型的模型拥有该评论。 ``` $comment = App\Comment::find(1);$commentable = $comment->commentable;
``` 3. 多对多的多态关联 //morphToMany 、morphedByMany 。一个标签有多种事物(模型),一种事物(模型)有多个标签4. 存在XX的记录
4.1 // 获取所有至少有一条评论的文章... $posts = App\Post::has('comments')->get(); 4.2 // 获取所有至少有三条评论的文章... $posts = Post::has('comments', '>=', 3)->get(); 4.3 // 获取所有至少有一条评论获得投票的文章... $posts = Post::has('comments.votes')->get(); 4.4 // 获取所有至少有一条评论包含foo字样的文章 $posts = Post::whereHas('comments', function ($query) { $query->where('content', 'like', 'foo%'); })->get();5. 不存在XX的记录
$posts = App\Post::doesntHave('comments')->get(); $posts = Post::whereDoesntHave('comments', function ($query) { $query->where('content', 'like', 'foo%'); })->get(); 6. 统计 //withCount7. 渴求式加载 //with() //解决频繁运行懒惰式加载增加数据库压力的问题
8. 懒惰渴求式加载 //load() //按需加载关联
9. 插入 & 更新关联模型 //save saveMany associate dissociate attach detach sync syncWithoutDetaching toggle
10. 触发父级时间戳 //在子模型中定义 protected $touches = ['post']; //post是父模型
11. 工程案例分析 App\ModelFilters\BaseFilter::handle()中的parent::handle()使用第三方的库赋与了应用在接收get参数"with[]"时可以根据定义好的模型关联关系来获取关联数据
11.1 用了这个库:https://packagist.org/packages/tucker-eric/eloquentfilter