一对一
用户和文章
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function post()
{
return $this->hasOne('App\Phone');
}
}
在当前场景下,Eloquent 会假设 Phone 模型有一个外间 user_id
$phone = User::find(1)->post;
反向关联
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function user()
{
return $this->belongsTo('App\User');
}
}
空对象模型, user 关联如果没有找到文章的作者,就会返回一个空的 App\User 模型。
可以理解返回一个默认值,还没有具体实践过
class Post extends Model
{
// 数组形式
public function user()
{
return $this->belongsTo('App\User')->withDefault([
'name' => '游客'
]);
}
// 闭包形式
public function user()
{
return $this->belongsTo('App\User')->withDefault(function($user) {
$user->name = '游客';
});
}
}
一对多
文章和评论
文章
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function comments()
{
return $this->hasMany('App\Comment');
}
}
评论
namespace App
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
public function post()
{
return $this->belongsTo('App\Post');
}
}
多对多
用户和角色
一个用户可以拥有多个角色,一个角色下面可以有多个用户
users, roles, role_user 三张表
role_user 表是以相关联的两个模型数据表、依照字母顺序排列命名的,并且包含 user_id 和 role_id 字段。
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function roles()
{
return $this->belongsToMany('App\Role');
}
}
namespace App;
use Illuminate\Databese\Eloquent\Model
class Role extends Model
{
public function users()
{
return $this->belongsToMany('App\User');
}
}
自定义中间表的场景
namespace App;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
public function users()
{
return $this->belongsToMany('App\User')->using('App\RoleUser');
}
}
namespace App;
use Illuminate\Database\Relationships\Pivot;
class RoleUser extends Pivot
{
}
远层一对多
一个 Country 模型可以通过中间的 User 模型获得多个 Post 模型
countries
id - integer
name - string
users
id - integer
country_id - integer
name - string
posts
id - integer
user_id - integer
title - string
hasManyThrough 方法的第一个参数是我们最终希望访问的模型名称,而第二个参数是中间模型的名称。
namespace App;
use Illuminate\Database\Eloquent\Model;
class Country extends Model
{
// 默认
public function posts()
{
return $this->hasManyThrough('App\Post', 'App\User');
}
// 自定义
第三个参数表示中间模型的外键名,第四个参数表示最终模型的外键名。
第五个参数表示本地键名,而第六个参数表示中间模型的本地键名:
public function posts()
{
return $this->hasManyThrough(
'App\Post',
'App\User',
'country_id', // 用户表外键
'user_id', // 文章表外键
'id', // 国家表
'id' //
);
}
}
多态关联
用户可以「评论」文章和视频
commentable_id 用来保存文章或者视频的 ID 值
commentable_type 用来保存所属模型的类名 (post, video)
posts
id - integer
title - string
body - text
videos
id - integer
title - string
url - string
comments
id - integer
body - text
commentable_id - integer
commentable_type - string
namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
public function commentable()
{
return $this->morphTo();
}
}
class Post extends Model
{
public function comments()
{
return $this->morphMany('App\Comment', 'commentable');
}
}
class Video extends Model
{
public function comments()
{
return $this->morphMany('App\Comment', 'commentable');
}
}
$commentable = App\Comment::find(1)->commtable();
返回 commentable 的 Post 或 Video 实例
多对多多态关联
Post 和 Video 两个模型都有一个 tags 方法,方法内部都调用了 Eloquent 类自身的 morphToMany 方法
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
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function tags()
{
return $this->morphToMany('App\Tag', 'taggable');
}
}
反向关联
class Tag extends Model
{
public function posts()
{
return $this->morphedByMany('App\Post', 'taggable');
}
public function videos()
{
return $this->morphedByMany('App\Video', 'taggable');
}
}
$tags = Post::find(1)->tags;
或者
$tag = Tag::find(1);
$videos = $tag->videos;
Dynamic properties allow you to access relationship methods as if they were properties defined on the model
模型中定义的关联,叫做 dynamic property(动态属性)