gpt4 book ai didi

php - 自定义 Laravel 关系?

转载 作者:可可西里 更新时间:2023-11-01 12:50:29 24 4
gpt4 key购买 nike

假设情况:假设我们有 3 个模型:

  • 用户
  • 角色
  • 权限

我们还假设 UserRole 具有多对多关系,而 Role权限

所以他们的模型可能看起来像这样。 (我故意让它们简短。)

class User
{
public function roles() {
return $this->belongsToMany(Role::class);
}
}

class Role
{
public function users() {
return $this->belongsToMany(User::class);
}

public function permissions() {
return $this->belongsToMany(Permission::class);
}
}

class Permission
{
public function roles() {
return $this->belongsToMany(Role::class);
}
}

如果您想获得用户的所有权限怎么办?没有BelongsToManyThrough.

似乎你有点被困在做一些感觉不太正确的事情,并且不适用于 User::with('permissions')User::有('权限')

class User
{
public function permissions() {
$permissions = [];
foreach ($this->roles as $role) {
foreach ($role->permissions as $permission) {
$permissions = array_merge($permissions, $permission);
}
}
return $permissions;
}
}

这个例子只是一个例子,大家不要过度解读。关键是,您如何定义自定义 关系?另一个例子可能是 facebook 评论与作者母亲之间的关系。很奇怪,我知道,但希望你明白了。自定义关系。怎么办?

在我看来,一个好的解决方案是以类似于 Laravel 中描述任何其他关系的方式来描述这种关系。返回 Eloquent Relation 的东西。

class User
{
public function permissions() {
return $this->customRelation(Permission::class, ...);
}
}

这样的东西已经存在了吗?

最佳答案

最接近解决方案的是@biship posted in the comments .您将在何处手动修改现有 Relation 的属性.这在某些情况下可能效果很好。确实,在某些情况下它可能是正确的解决方案。但是,我发现我不得不剥离所有 constraints添加者 Relation并手动添加任何新的 constraints我需要。

我的想法是……如果您要剥离 constraints每次这样 Relation只是“裸”。为什么不定制 Relation不添加任何 constraints本身并采用 Closure帮助促进添加 constraints

解决方案

像这样的东西对我来说似乎很管用。至少,这是基本概念:

class Custom extends Relation
{
protected $baseConstraints;

public function __construct(Builder $query, Model $parent, Closure $baseConstraints)
{
$this->baseConstraints = $baseConstraints;

parent::__construct($query, $parent);
}

public function addConstraints()
{
call_user_func($this->baseConstraints, $this);
}

public function addEagerConstraints(array $models)
{
// not implemented yet
}

public function initRelation(array $models, $relation)
{
// not implemented yet
}

public function match(array $models, Collection $results, $relation)
{
// not implemented yet
}

public function getResults()
{
return $this->get();
}
}

尚未实现的方法用于预先加载,必须声明为抽象方法。我还没有那么远。 :)

还有一个特性使这个新的 Custom关系更易于使用。

trait HasCustomRelations
{
public function custom($related, Closure $baseConstraints)
{
$instance = new $related;
$query = $instance->newQuery();

return new Custom($query, $this, $baseConstraints);
}
}

用法

// app/User.php
class User
{
use HasCustomRelations;

public function permissions()
{
return $this->custom(Permission::class, function ($relation) {
$relation->getQuery()
// join the pivot table for permission and roles
->join('permission_role', 'permission_role.permission_id', '=', 'permissions.id')
// join the pivot table for users and roles
->join('role_user', 'role_user.role_id', '=', 'permission_role.role_id')
// for this user
->where('role_user.user_id', $this->id);
});
}
}

// app/Permission.php
class Permission
{
use HasCustomRelations;

public function users()
{
return $this->custom(User::class, function ($relation) {
$relation->getQuery()
// join the pivot table for users and roles
->join('role_user', 'role_user.user_id', '=', 'users.id')
// join the pivot table for permission and roles
->join('permission_role', 'permission_role.role_id', '=', 'role_user.role_id')
// for this permission
->where('permission_role.permission_id', $this->id);
});
}
}

You could now do all the normal stuff for relations without having to query in-between relations first.

Github

我先放了all this on Github以防有更多人对这样的事情感兴趣。在我看来,这仍然是一种科学实验。但是,嘿,我们可以一起解决这个问题。 :)

关于php - 自定义 Laravel 关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39213022/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com