ardalanamini/laravel-custom-relation

当库存关系不足以使用时,创建自己的自定义关系

v0.1.5 2023-09-16 15:26 UTC

This package is not auto-updated.

Last update: 2024-09-28 21:01:08 UTC


README

当库存关系不足以使用时,创建自己的自定义关系

[目录]

当以下情况发生时使用...

  • 没有任何库存关系符合要求。(BelongsToManyThrough等)

安装

推荐的安装方法是使用composer

composer require ardalanamini/laravel-custom-relation

示例

假设我们有3个模型

  • User
  • Role
  • Permission

假设UserRole之间是多对多关系,而RolePermission之间也是多对多关系。

因此,它们的模型可能看起来像这样。(我有意让它们简短。)

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);
    }
}

如果你想要获取某个User的所有Permission或者所有具有特定PermissionUser呢?在Laravel中没有库存关系可以描述这种情况。我们需要的是BelongsToManyThrough,但是在库存Laravel中并不存在。

解决方案

首先,确保你的模型使用了HasCustomRelations特性。然后,像这样定义自定义关系。

use LaravelCustomRelation\HasCustomRelations;

class User {
    use HasCustomRelations;

    /**
     * Get the related permissions
     *
     * @return Illuminate\Database\Eloquent\Relations\Relation
     */
    public function permissions() {
        return $this->custom(
            Permission::class,

            // add constraints
            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);
            },

            // add eager constraints
            function ($relation, $models) {
                $relation->getQuery()->whereIn(
                  'role_user.user_id',
                  collect($models)->map(function ($value) {
                      return $value->getKey();
                  })->values()->unique()->sort()->all()
               );
            }
        );
    }
}
use LaravelCustomRelation\HasCustomRelations;

class Permission {
    use HasCustomRelations;

    /**
     * Get the related users
     *
     * @return Illuminate\Database\Eloquent\Relations\Relation
     */
    public function users() {
        return $this->custom(
            User::class,

            // constraints
            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);
            },

            // eager constraints
            function ($relation, $models) {
                $relation->getQuery()->whereIn(
                    'permission_role.permission_id',
                    collect($models)->map(function ($value) {
                        return $value->getKey();
                    })->values()->unique()->sort()->all()
                );
            }
        );
    }
}

你现在可以像处理正常关系一样进行所有操作,而无需在关系之间进行查询。