johnnyfreeman/laravel-custom-relation

此包已被 废弃,不再维护。没有建议的替代包。

当库存关系不够用时,使用自定义关系。

0.0.3 2016-09-03 22:08 UTC

This package is auto-updated.

Last update: 2021-02-11 15:01:46 UTC


README

这个仓库是一项科学实验,旨在寻找解决 这个问题 的方法。现在我认为处理自定义关系的更好方法是创建一个新的类,可能扩展现有的其中一个类。

Laravel 自定义关系

当库存关系不够用时,使用自定义关系。

在以下情况下使用此功能...

  • 没有现成的关系符合要求。(如 BelongsToManyThrough 等)

安装

推荐使用 composer 安装。

composer require johnnyfreeman/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', $relation->getKeys($models));
            }
        );
    }
}
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', $relation->getKeys($models));
            }
        );
    }
}

现在你可以执行所有常规的关联操作,而无需首先在关联之间进行查询。