Laravel的 Eloquent ORM 中Scopes和accotiate()
在 Laravel 的 Eloquent ORM 中,Scopes(作用域)是一种用于封装数据库查询逻辑的便捷方式。Scopes 可以帮助你在模型中定义常用的查询逻辑,并使其在需要时更易于重用和调用。
Scopes 有两种类型:全局作用域(Global Scopes)和局部作用域(Local Scopes)。
局部作用域(Local Scopes)
局部作用域是一种在模型中定义的查询方法,你可以通过调用这个方法来应用特定的查询逻辑。
定义局部作用域
你可以在模型中定义一个局部作用域方法。局部作用域方法的名称应该以 scope
开头,并且在调用时不需要包括 scope
前缀。
例如,在 User
模型中定义一个 scopeActive
局部作用域:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
// 定义一个局部作用域来筛选激活的用户
public function scopeActive($query)
{
return $query->where('active', 1);
}
}
使用局部作用域
使用局部作用域时,只需在查询中调用不带 scope
前缀的方法:
use App\Models\User;
// 获取所有激活的用户
$activeUsers = User::active()->get();
你还可以将多个作用域链式调用:
// 定义另一个作用域来筛选管理员用户
public function scopeAdmin($query)
{
return $query->where('role', 'admin');
}
// 获取所有激活的管理员用户
$activeAdmins = User::active()->admin()->get();
全局作用域(Global Scopes)
全局作用域是你希望在模型的所有查询中自动应用的查询逻辑。定义全局作用域时,你需要创建一个实现 Scope
接口的类,并在模型中注册该作用域。
定义全局作用域
创建一个全局作用域类:
namespace App\Scopes;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;
class ActiveScope implements Scope
{
public function apply(Builder $builder, Model $model)
{
$builder->where('active', 1);
}
}
注册全局作用域
在模型中注册全局作用域:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Scopes\ActiveScope;
class User extends Model
{
protected static function booted()
{
static::addGlobalScope(new ActiveScope);
}
}
使用全局作用域
全局作用域会自动应用于所有的查询:
use App\Models\User;
// 获取所有激活的用户
$users = User::all(); // 仅返回激活的用户
如果你想在特定查询中忽略全局作用域,可以使用 withoutGlobalScope
方法:
use App\Models\User;
use App\Scopes\ActiveScope;
// 获取所有用户,包括未激活的用户
$allUsers = User::withoutGlobalScope(ActiveScope::class)->get();
总结
- 局部作用域:在模型中定义以
scope
开头的方法,用于封装特定的查询逻辑,调用时省略scope
前缀。 - 全局作用域:创建一个实现
Scope
接口的类,并在模型中注册该作用域,自动应用于所有查询。
使用作用域可以使你的查询逻辑更加清晰、可重用,并且更易于维护。
accotiate()
associate()
方法是 Laravel 的 Eloquent ORM 中的一个功能强大的方法,用于在两个模型之间建立关联关系。它通常用于处理多对多(Many-to-Many)的关系。
让我们通过一个示例来更好地理解 associate()
方法的用法。假设我们有两个模型:User
和 Role
。每个用户可以有多个角色,每个角色也可以被多个用户拥有。这就是一个典型的多对多关系。
首先,我们需要在两个模型中定义关联关系。在 User
模型中:
public function roles()
{
return $this->belongsToMany(Role::class);
}
在 Role
模型中:
public function users()
{
return $this->belongsToMany(User::class);
}
现在,假设我们有一个用户实例 $user
和一个角色实例 $role
。我们可以使用 associate()
方法将这个角色与用户建立关联关系:
$user->roles()->associate($role);
$user->save();
这个过程实际上做了以下几件事:
- 在中间表(通常命名为
role_user
)中插入一条新记录,将$user
的 ID 和$role
的 ID 关联起来。 - 保存
$user
模型实例,确保关联关系被持久化到数据库中。
如果我们想要删除某个用户与某个角色之间的关联关系,可以使用 detach()
方法:
$user->roles()->detach($role);
$user->save();
这将从中间表中删除对应的记录,断开两个模型之间的关联关系。
除了 associate()
和 detach()
方法,Eloquent 还提供了其他一些方法来管理多对多关系,例如:
sync()
: 同步关联关系,替换现有的关联。toggle()
: 切换关联关系,如果存在则删除,如果不存在则添加。attach()
: 添加新的关联关系。
总的来说,associate()
方法是 Eloquent 中管理多对多关系的一个重要工具,它可以帮助开发者更方便地建立和维护模型之间的复杂关联关系。