Laravel 中的模型操作非常强大,但是光看文档的话使用的各个参数相对而言比较绕,蹭着还没有被绕晕,赶紧写个笔记来巩固一下,也方便以后查看。
- 一对一关系
举个例子,一个用户拥有一个对应的个人扩展信息。
users表结构与表数据为:
| id | name | password | remember_token | created_at | updated_at | |
|---|---|---|---|---|---|---|
| 1 | name | alex@163.com | 123123 | 123123 | 2019-02-13 23:59:59 | 2019-02-13 23:59:59 |
profiles表结构与表数据为:
| id | user_id | realname | phone | created_at | updated_at |
|---|---|---|---|---|---|
| 1 | 1 | 张三 | 13500001111 | 2019-02-13 23:59:59 | 2019-02-13 23:59:59 |
有两个表,Laravel中的默认规定是创建User来对应users表,Profile类来对应profiles表。两个模型之间是一对一的关系,关系中不需要中间表。
定义User模型
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* 获取用户关联的个人信息
*/
public function profile() {
/**
* hasOne三个参数
* 关联的模型 Profile
* 关联模型Profile的外键 user_id
* 当前模型 User 的主键 id
*/
return $this->hasOne(Profile::class, 'user_id', 'id');
}
}
调用形式为:
$profile = User::first()->profile;
echo $profile->realname . PHP_EOL; // 张三
echo $profile->phone . PHP_EOL; // 13500001111
// 修改属性并保存到数据库
// 方法一
$profile->phone = '13566663333';
$profile->save();
// 方法二
$profile->save(['phone' => '13566663333']);
echo $profile->phone . PHP_EOL; // 13566663333
Laravel中不仅仅可以正向关联,还可以定义反向关联。这个通常是我们知道用户的真实姓名realname,但是像知道对应我们系统的具体哪个用户。
定义Profile模型
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Profile extends Model
{
/**
* 获取此个人信息对应的系统用户信息
*/
public function user()
{
/**
* belongsTo 参数
* 关联的数据模型 User
* 当前模型 Phone 的外键 user_id
* 关联模型 User 的主键 id
*/
return $this->belongsTo(User::class, 'user_id', 'id');
}
}
调用形式为:
$user = Profile::where(id, 1)->first()->user;
$user->name = 'HolyShit';
$user->save();
echo $user->name . PHP_EOL; // HolyShit
- 一对多关系
举个例子,一个文章对应着多个评论信息
posts表结构与表数据为:
| id | title | content | created_at | updated_at |
|---|---|---|---|---|
| 1 | 标题1 | 文章内容 | 2019-09-10 18:10:00 | 2019-09-10 18:10:00 |
comments表结构与表数据为:
| id | post_id | user_id | parent_id | content | created_at | updated_at |
|---|---|---|---|---|---|---|
| 1 | 1 | 1 | 0 | 不错支持楼主 | 2019-09-10 18:10:00 | 2019-09-10 18:10:00 |
| 2 | 1 | 1 | 0 | 66666 | 2019-09-10 18:10:00 | 2019-09-10 18:10:00 |
| 3 | 1 | 1 | 0 | 必须支持 | 2019-09-10 18:10:00 | 2019-09-10 18:10:00 |
定义Post模型
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
/**
* 获取Post信息对应的评论
*/
public function comments() {
/**
* hasMany三个参数
* 关联的模型 Comment
* 关联模型Comment的外键 post_id
* 当前模型 Post 的主键 id
*/
return $this->hasMany(Comment::class, 'post_id', 'id');
}
}
调用方法为:
$comments = Post::first()->comments;
foreach($comments as $comment) {
echo $comment->content . PHP_EOL;
}
定义Comment模型反向关联
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
/**
* 获取Post信息
*/
public function post() {
/**
* belongsTo 三个参数
* 关联的数据模型 Post
* 当前模型 Comment 的外键 post_id
* 关联模型 Post 的主键 id
*/
return $this->belongsTo(Post::class, 'post_id', 'id');
}
}
调用方法为:
$post = Comment::first()->post;
echo $post->title . PHP_EOL; // 标题1
- 多对多关系
举个例子,一个用户可以有多个角色,一个角色可以有多个用户
users用户表结构和表数据为:
| id | name | created_at | updated_at |
|---|---|---|---|
| 1 | 张三 | 2019-09-10 18:10:00 | 2019-09-10 18:10:00 |
| 2 | 李四 | 2019-09-10 18:10:00 | 2019-09-10 18:10:00 |
| 3 | 王五 | 2019-09-10 18:10:00 | 2019-09-10 18:10:00 |
roles角色表结构和表数据为:
| id | name | created_at | updated_at |
|---|---|---|---|
| 1 | 超级管理员 | 2019-09-10 18:10:00 | 2019-09-10 18:10:00 |
| 2 | 管理员 | 2019-09-10 18:10:00 | 2019-09-10 18:10:00 |
| 3 | 普通用户 | 2019-09-10 18:10:00 | 2019-09-10 18:10:00 |
| 4 | 销售 | 2019-09-10 18:10:00 | 2019-09-10 18:10:00 |
role_user角色用户关系表和表数据为:
| role_id | user_id | created_at | updated_at |
|---|---|---|---|
| 1 | 1 | 2019-09-10 18:10:00 | 2019-09-10 18:10:00 |
| 2 | 3 | 2019-09-10 18:10:00 | 2019-09-10 18:10:00 |
| 3 | 3 | 2019-09-10 18:10:00 | 2019-09-10 18:10:00 |
| 4 | 1 | 2019-09-10 18:10:00 | 2019-09-10 18:10:00 |
| 2 | 2 | 2019-09-10 18:10:00 | 2019-09-10 18:10:00 |
| 4 | 2 | 2019-09-10 18:10:00 | 2019-09-10 18:10:00 |
| 3 | 2 | 2019-09-10 18:10:00 | 2019-09-10 18:10:00 |
定义User模型
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* 用户拥有的角色
*/
public function roles()
{
/**
* belongsToMany 参数描述
* 关联的模型类名 Role
* 中间表表名
* 关联模型 Role 在中间模型的外键名称 role_id
* 当前模型 User 在中间模型中的外键名称 user_id
*/
return $this->belongsToMany(Role::class, 'role_user', 'user_id', 'role_id')->withPivot('created_at', 'updated_at');
}
}
调用方法为:
$roles = User::find(1)->roles;
foreach($roles as $role) {
echo $role->name . PHP_EOL;
}
// 输出结果:
// 超级管理员
// 销售
定义Role模型
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
/**
* 角色下的用户
*/
public function users()
{
/**
* belongsToMany 参数描述
* 关联的模型类名 User
* 中间表表名
* 关联模型 User 在中间模型的外键名称 user_id
* 当前模型 Role 在中间模型中的外键名称 role_id
*/
return $this->belongsToMany(User::class, 'role_user', 'user_id', 'role_id')->withPivot('created_at', 'updated_at');
}
}
调用方法为:
$users = Role::find(2)->users;
foreach ($users as $user) {
echo $user->name . PHP_EOL;
}
// 输出结果:
// 李四
// 王五
上面我们使用了withPivot方法,他是针对多对多中的中间表role_user多出了两个字段 created_at 和 updated_at,如果你需要访问这两个字段,必须在关联的时候指出。