一、描述1vs1关系php
例如好比又两张表,一张用户表,一张手机表,一个用户只有一个手机,一个手机也只属于一我的,就表达了一对一的关系ide
class User extends Eloquent {
//一对一
public function phone() {
return $this->hasOne('Phone'); // this matches the Eloquent model
}
函数
class Phone extends Eloquent {
public function user() {
return $this->belongsTo('user'); // this matches the Eloquent model
}post
咱们能够总结出,在一对一关系中,主表(也就是没有保存user_id表的那个表),用hasOne表示,另一个表,保存了user_id的,用belongsTo来表述。换句话说,当咱们看到一个表有blongsTo的时候,若是后面没有带参数,也就表明着这个表利用方法名_id来跟前面的表关联.this
$account = User::find(10)->phone;
这里最难的地方在于后面的两个 foreign_key 和 local_key 的设置,你们能够就此记住:在 User 类中,不管 hasOne 谁,第二个参数都是 `user_id`,第三个参数通常都是 `id`。因为前面的 `find(10)` 已经锁定了 id = 10,因此这段函数对应的 SQL 为: `select * from phone where user_id=10`。spa
这段代码除了展现了一对一关系该如何使用以外,还传达了三点信息,也是我对于你们使用 Eloquent 时候的建议:code
1. 每个 Model 中都指定表名视频
2. has one account 这样的关系写成 `hasOneAccount()` 而不是简单的 `account()`对象
3. 每次使用模型间关系的时候都写全参数,不要省略string
二、描述1vs多关系
例如班级表,学生表,一个班级有不少名学生,一个学生只在一个班级,所以class表跟student表是一对多关系
class Squad extends Eloquent {
//一对多
public function student() {
return $this->hasMany('Student');
}
class Student extends Eloquent {
public function squad() {
return $this->belongsTo('Squad');
}
咱们能够总结出,在一对多关系中,主表(也就是没有保存squad_id表的那个表),用hasMany表示,另一个表,保存了squad_id的,用 belongsTo来表述。
三、描述多对多关系
例如角色表,用户表,一个角色有多个用户,一个用户能够拥有多个角色
Class Role extentds Eloquent{
public function users{
return $this->belongsToMany('App\User','user_roles');
}
}
Class User extentds Eloquent{
//多对多关系咱们都用复数
public function roles{
return $this->belongsToMany('App\role','user_role');
//(被关联模型,中间表名,关系模型(本类的外键id)的外键名称,链接到的外键名)
return $this->belongsToMany('App\Role', 'user_roles', 'user_id', 'role_id');
}
}
PS:其实咱们并不是必定要在咱们的模型中写这么多可能另咱们本身都费解的东西,只是根据须要咱们须要进行某些查询的时候才写,举个简单例子,若是咱们只须要查一个角色有多少个用户,而咱们发现角色跟用户是多对多关系,咱们就能够在Role表中写个User方法。若是咱们须要查一个班级的全部学生,咱们发现班级跟学生是一对多关系,咱们就能够在班级模型中写Student方法,用到hasMany。凡是看到有belongsToMany的该模型跟括号里面的确定是多对多。
四、传统多态模型
文章有点赞功能,评论也有点赞功能,咱们的点赞表就有一个字段用来记录表的类型,id记录了文章或评论的id
posts id - integer title - string body - text comments id - integer post_id - integer body - text likes id - integer likeable_id - integer likeable_type - string
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Like extends Model{ /** * 获取所属的likeable模型 */ public function likeable() { return $this->morphTo(); } } class Post extends Model{ /** * 获取该文章的全部点赞 */ public function likes() { return $this->morphMany('App\Like', 'likeable'); } } class Comment extends Model{ /** * 获取该评论的全部点赞 */ public function likes() { return $this->morphMany('App\Like', 'likeable'); } }
传统的多态比较好理解,就是在文章或评论里面用一个morphMany方法进行关联。传统的多态关联是基于多个一对多表之间的对应关系。
五、多对多的多态关联
多对多的多态关联就稍微复杂点,利用到了相似于咱们说的中间表概念,例如咱们的文章跟视频均可能有多个标签,因而咱们就有了标签表跟标签关联表。
posts id - integer name - string videos id - integer name - string tags id - integer name - string taggables tag_id - integer taggable_id - integer taggable_type - string
关联主体表用morphTomany:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Post extends Model{ /** * 获取指定文章全部标签 */ public function tags() { return $this->morphToMany('App\Tag', 'taggable'); } }
被关联也就是多态模型表用morphedByMany。
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Tag extends Model{ /** * 获取全部分配该标签的文章 */ public function posts() { return $this->morphedByMany('App\Post', 'taggable'); } /** * 获取分配该标签的全部视频 */ public function videos() { return $this->morphedByMany('App\Video', 'taggable'); } }
这是一个主体经过某个中间表在另一个表中多态的例子,还有一种
通知表notifies,通知发送对象notify_pivots表(一条通知可能发送给一我的,也多是一个班级,也多是一个学校),所以这就造成了notifies表经过users表,school表,squards表跟notify_pivots表关联。
notify模型
public function schools() { return $this->morphedByMany('App\Models\School','notify_pivots'); } // public function squads() { return $this->morphedByMany('App\Models\Squad','notify_pivots'); } // 这个是消息的接收者是学生或者老师或者其它的方法 public function users() { return $this->morphedByMany('App\Models\User','notify_pivots'); }