一对一php
<?php class User extends Model{ // 获取关联到用户的手机 public function phone() { // Phone 模型默认有一个 user_id 外键 return $this->hasOne('App\Phone'); // 外键应该在父级上有一个与之匹配的id(或者自定义 $primaryKey) // return $this->hasOne('App\Phone', 'foreign_key'); // 用User的local_key,匹配Phone的foreign_key // return $this->hasOne('App\Phone', 'foreign_key', 'local_key'); } } $phone = User::find(1)->phone; // 获取用户的手机模型
相对的关联数据库
<?php class Phone extends Model { // 获取手机对应的用户 public function user() { return $this->belongsTo('App\User'); // return $this->belongsTo('App\User', 'foreign_key'); // return $this->belongsTo('App\User', 'foreign_key', 'other_key'); } } $user = Phone::find(1)->user; // 查询phone的id=1对应的user $user = Phone::where('number','188**')->first()->user; // 查询电话为188的用户
一对多数组
class User extends Model{ // 获取文章 public function article() { return $this->hasMany('App\Comment'); // return $this->hasMany('App\Comment', 'foreign_key'); // return $this->hasMany('App\Comment', 'foreign_key', 'local_key'); } } $articles = User::find(1)->article; // 返回 userid为1 的全部文章 $article = User::find(1)->article()->where('title', 'aa')->first(); // 返回某一篇
一对多(逆向)闭包
class Article extends Model{ public function user() { return $this->belongsTo('App\User'); // return $this->belongsTo('App\Post', 'foreign_key'); // return $this->belongsTo('App\Post', 'foreign_key', 'other_key'); } } $user = Article::find($id)->user; // 返回文章的做者
多对多app
须要三张数据表:users、roles 和 role_user,
role_user 表为关系表,默认按照关联模型名的字母顺序命名,而且包含 user_id 和 role_id 两个列。
class User extends Model{ /** * 用户角色 */ public function roles() { //默认去role_user查找关系 // return $this->belongsToMany('App\Role'); return $this->belongsToMany('App\Role',"role_users"); // 定义键值 // return $this->belongsToMany('App\Role', 'user_roles', 'user_id', 'role_id'); } } $roles = User::find(1)->roles; // 返回 [{"id":1,"name":"SuperManager","pivot":{"user_id":1,"role_id":1}},{"id":2,"name":"Manager","pivot":{"user_id":1,"role_id":2}}] $roles = User::find(1)->roles()->orderBy('name')->get(); // 条件约束
注意咱们获取到的每个 Role 模型都被自动赋上了 pivot 属性。该属性包含一个表明中间表的模型,而且能够像Eloquent 模型同样使用。
若是你的 pivot 表包含额外的属性,必须在定义关联关系时进行指定:post
return $this->belongsToMany('App\Role')->withPivot('column1', 'column2');
若是你想要你的 pivot 表自动包含created_at 和 updated_at 时间戳,在关联关系定义时使用 withTimestamps 方法:this
return $this->belongsToMany('App\Role')->withTimestamps();
过中间表字段过滤关联关系code
return $this->belongsToMany('App\Role')->wherePivot('approved', 1); return $this->belongsToMany('App\Role')->wherePivotIn('priority', [1, 2]);
存在的关联查询ci
// 获取全部至少有一条评论的文章... $posts = App\Post::has('comments')->get(); 你还能够指定操做符和数目来自定义查询: // 获取全部至少有三条评论的文章... $posts = Post::has('comments', '>=', 3)->get(); 还可使用”.“来构造嵌套 has 语句,例如,你要获取全部至少有一条评论及投票的文章: // 获取全部至少有一条评论得到投票的文章... $posts = Post::has('comments.votes')->get(); 若是你须要更强大的功能,可使用 whereHas 和 orWhereHas 方法将 where 条件放到 has 查询上,这些方法容许你添加自定义条件约束到关联关系条件约束,例如检查一条评论的内容: // 获取全部至少有一条评论包含foo字样的文章 $posts = Post::whereHas('comments', function ($query) { $query->where('content', 'like', 'foo%'); })->get();
无关联结果查询文档
// 获取全部没有评论的博客文章 $posts = App\Post::doesntHave('comments')->get(); // 检查评论内容: $posts = Post::whereDoesntHave('comments', function ($query) { $query->where('content', 'like', 'foo%'); })->get();
统计关联模型
若是你想要在不加载关联关系的状况下统计关联结果数目,可使用 withCount 方法,该方法会放置一个 {relation}_count 字段到结果模型
$posts = App\Post::withCount('comments')->get(); foreach ($posts as $post) { echo $post->comments_count; } // 添加约束条件到查询同样来添加多个关联关系的“计数”: $posts = Post::withCount(['votes', 'comments' => function ($query) { $query->where('content', 'like', 'foo%'); }])->get(); echo $posts[0]->votes_count; echo $posts[0]->comments_count; // 为关联关系计数结果设置别名,从而容许在一个关联关系上进行多维度计数: $posts = Post::withCount([ 'comments', 'comments AS pending_comments' => function ($query) { $query->where('approved', false); } ])->get(); echo $posts[0]->comments_count; echo $posts[0]->pending_comments_count;
当以属性方式访问数据库关联关系的时候,关联关系数据是“懒惰式加载”的,这意味着关联关系数据直到第一次访问的时候才被加载。
$books = App\Book::all(); foreach ($books as $book) { echo $book->author->name; } // 该循环要执行26次查询:1次是获取书自己,剩下的25次查询是为每一本书获取其做者。
$books = App\Book::with('author')->get(); foreach ($books as $book) { echo $book->author->name; } // 在该操做中,只执行两次查询便可: // select * from books // select * from authors where id in (1, 2, 3, 4, 5, ...)
渴求式加载多个关联关系
$books = App\Book::with('author', 'publisher')->get();
嵌套的渴求式加载
// 加载全部书的做者及全部做者的我的联系方式: $books = App\Book::with('author.contacts')->get();
带条件约束的渴求式加载
// 加载 title 包含 first 的文章 $users = App\User::with(['posts' => function ($query) { $query->where('title', 'like', '%first%'); }])->get(); // 加载按created_at倒序的的文章 $users = App\User::with(['posts' => function ($query) { $query->orderBy('created_at', 'desc'); }])->get();
懒惰渴求式加载
$books = App\Book::all(); if ($someCondition) { $books->load('author', 'publisher'); } // 设置更多的查询条件到渴求式加载查询上,能够传递一个闭包到 load 方法: $books->load(['author' => function ($query) { $query->orderBy('published_date', 'asc'); }]);
save 方法
$comment = new App\Comment(['message' => 'A new comment.']); $post = App\Post::find(1); $post->comments()->save($comment); // save 方法会自动添加 post_id 值到新的Comment 模型。
保存多个关联模型,可使用 saveMany 方法:
$post = App\Post::find(1); $post->comments()->saveMany([ new App\Comment(['message' => 'A new comment.']), new App\Comment(['message' => 'Another comment.']), ]);
create方法
该方法接收属性数组、建立模型、而后插入数据库。save 和 create 的不一样之处在于 save 接收整个 Eloquent 模型实例而 create 接收原生 PHP 数组:
使用 create 方法以前确保先浏览属性批量赋值文档。
$post = App\Post::find(1); $comment = $post->comments()->create([ 'message' => 'A new comment.', ]);
从属关联关系
更新 belongsTo 关联, 使用associate 方法,该方法会在子模型设置外键:
$account = App\Account::find(10); $user->account()->associate($account); $user->save();
移除 belongsTo 关联的时候,使用dissociate 方法。该方法会设置关联关系的外键为 null:
$user->account()->dissociate(); $user->save();
假定一个用户可能有多个角色,同时一个角色属于多个用户,要经过在链接模型的中间表中插入记录附加角色到用户上,可使用 attach 方法:
$user = App\User::find(1); $user->roles()->attach($roleId); // 以数组形式传递额外被插入数据到中间表: $user->roles()->attach($roleId, ['expires' => $expires]);
移除一个多对多关联记录,使用 detach 方法。detach 方法将会从中间表中移除相应的记录;
可是,两个模型在数据库中都保持不变:
// 从指定用户中移除角色... $user->roles()->detach($roleId); // 从指定用户移除全部角色... $user->roles()->detach();
接收数组形式的 ID 做为输入:
$user = App\User::find(1); $user->roles()->detach([1, 2, 3]); $user->roles()->attach([1 => ['expires' => $expires], 2, 3]);
同步关联
sync 方法接收数组形式的 ID 并将其放置到中间表
// 任何不在该数组中的 ID 对应记录将会从中间表中移除 $user->roles()->sync([1, 2, 3]); // 还能够和 ID 一块儿传递额外的中间表值: $user->roles()->sync([1 => ['expires' => true], 2, 3]); // 若是不想要脱离存在的ID,可使用syncWithoutDetaching 方法: $user->roles()->syncWithoutDetaching([1, 2, 3]);
切换关联
// 若是当前没有附加,则附加:若是给定ID当前被附加,则取消附加 $user->roles()->toggle([1, 2, 3]);
在中间表上保存额外数据
// 接收额外中间表属性数组做为第二个参数: App\User::find(1)->roles()->save($role, ['expires' => $expires]);
更新中间表记录 updateExistingPivot
// 更新中间表中已存在的行,接收中间记录外键和属性数组进行更新 $user = App\User::find(1); $user->roles()->updateExistingPivot($roleId, $attributes);
当一个模型属于另一个时,子模型更新时父模型的时间戳也被更新将颇有用
例如,当 Comment 模型被更新时,你可能想要”触发“更新其所属模型 Post 的updated_at 时间戳。Eloquent 使得这项操做变得简单,只须要添加包含关联关系名称的 touches 属性到子模型便可:
class Comment extends Model{ // 触发的全部关联关系 protected $touches = ['post']; // 关联关系 public function post() { return $this->belongsTo('App\Post'); } }
更新 Comment 时,所属模型 Post 将也会更新其 updated_at 值
$comment = App\Comment::find(1); $comment->text = 'Edit to this comment!'; $comment->save();