首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BelongsToMany中关联类别的Laravel过滤用户

BelongsToMany中关联类别的Laravel过滤用户
EN

Stack Overflow用户
提问于 2020-12-27 06:03:52
回答 1查看 245关注 0票数 0

在我们的应用程序中,每个类别和用户可以关联在一起。

每个类别可以与一个或多个用户关联,每个用户可以关联一个或多个类别。

例如,假设我们有这样的类别结构:

代码语言:javascript
复制
application
     web
         php
            laravel
            lumen
         web_design
            html
            css
            js 
     mobile    
         java
         flutter

在这种结构中,每个类别可以是一个或多个子类,我们在数据库结构中使用parent_id来实现它们。

现在,这些类别中的每一个或与一个或多个用户相关联的一些类别,例如:

代码语言:javascript
复制
application (Alfred)
     web (Alfred)
         php (Alfred)
            laravel (Alfred)
            lumen   (Alfred)
         web_design (Alfred)
            html (Alfred)
            css  (Alfred)
            js   (Alfred)
     mobile  (Alfred)   
         java (Alfred)
         flutter (Alfred)

此结构中与此用户关联的所有类别:(Alfred)和每个类别都可以与另一个用户关联,例如:

代码语言:javascript
复制
application (Alfred)
     web (Alfred)
         php (Alfred,Ella)
            laravel (Alfred,Ella)
            lumen   (Alfred,Ella)
         web_design (Alfred,Elizabeth)
            html (Alfred,Elizabeth)
            css  (Alfred,Elizabeth)
            js   (Alfred,Elizabeth)
     mobile  (Alfred,Jack)   
         java (Alfred,Jack)
         flutter (Alfred,Jack)

或者换句话说,你可以假设我们有这样的结构:

代码语言:javascript
复制
application (Alfred)
     web (Alfred)
         php (Alfred, Ella)
            laravel (Alfred, Ella)
            lumen   (Alfred,Ella ,Linda)
         web_design (Alfred, Elizabeth)
            html (Alfred,Elizabeth)
            css  (Alfred,Elizabeth)
            js   (Alfred,Elizabeth, Scarlett)
     mobile  (Alfred, Jack)   
         java (Alfred, Jack)
         flutter (Alfred, Jack, Jim)

这个用户是BelongsToManyRole,我们将它们同步到数据库中。

阿尔弗雷德:is-portal-manager

  • Ella:is-manager

  • Elizabeth:is-manager

  • Jack:is-editor

  • Scarlett:is-writer

  • Jim:is-writer

我们使用category_user表来同步此结构以关联类别和用户。

然后我们有五个表:userscategoriesroles和中间表:category_userrole_user

migrations数据库和表:

代码语言:javascript
复制
Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->foreignId('user_id')->nullable()->constrained();
    $table->string('name');
    $table->string('family');
    $table->string('username');
    //...
});

Schema::create('categories', function (Blueprint $table) {
    $table->id();
    $table->unsignedBigInteger('parent_id')->nullable();
    $table->string('name');
    //...
});

Schema::create('roles', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('label');
    $table->timestamps();
});

Schema::create('category_user', function (Blueprint $table) {
    $table->foreignId('category_id')->constrained()->onDelete('cascade');
    $table->foreignId('user_id')->constrained()->onDelete('cascade');
    $table->primary(['category_id', 'user_id']);
});

Schema::create('role_user', function (Blueprint $table) {
    $table->foreignId('role_id')->constrained()->onDelete('cascade');
    $table->foreignId('user_id')->constrained()->onDelete('cascade');
    $table->primary(['role_id', 'user_id']);
});

最后,我们的问题是什么,

我们希望获得与category_user表关联和定义的日志用户类别,这意味着当Alfred登录到系统时应该拥有与它们关联的所有类别。(一个或多个类别),另一个用户应该具有相同的策略,

是-门户-管理器(所有类别的子类别:应用程序、web、php、laravel、流明、web_design、html、css、js、移动、java、flutter)

  • Ella : is-manager (php、laravel、lumen)

  • Elizabeth : is-manager (web_design、html、css、js)

  • Jack :is-编辑器(移动、java、flutter)

  • Scarlett : is-writer (js)

  • Jim :is-写(颤音)

完全结构

代码语言:javascript
复制
application (Alfred: is-portal-manager)
     web (Alfred: is-portal-manager)
         php (Alfred: is-portal-manager, Ella: is-manager)
            laravel (Alfred: is-portal-manager, Ella: is-manager)
            lumen   (Alfred: is-portal-manager,Ella: is-manager ,Linda)
         web_design (Alfred: is-portal-manager, Elizabeth: is-manager)
            html (Alfred: is-portal-manager,Elizabeth: is-manager)
            css  (Alfred: is-portal-manager,Elizabeth: is-manager)
            js   (Alfred: is-portal-manager,Elizabeth: is-manager, Scarlett: is-writer)
     mobile  (Alfred: is-portal-manager, Jack: is-editor)   
         java (Alfred: is-portal-manager, Jack: is-editor)
         flutter (Alfred: is-portal-manager, Jack: is-editor, Jim: is-writer)

型号:

代码语言:javascript
复制
class Category extends Model
{
    public function parent(): BelongsTo
    {
        return $this->belongsTo(Category::class, 'parent_id', 'id', 'parent');
    }

    public function subcategories(): HasMany
    {
        return $this->hasMany(Category::class, 'parent_id', 'id');
    }

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

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

class User extends Authenticatable
{
    use Notifiable;

    /**
     * Get the parent User to which the current User belongs.
     */
    public function parent(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    /**
     * Get all Users which belong to the current User.
     */
    public function kids(): HasMany
    {
        return $this->hasMany(User::class);
    }

    public function categories(): BelongsToMany
    {
        $categories = $this->belongsToMany(Category::class);
        return $categories;
    }

    /**
     * Determine whether the current user has prime Role of Portal Manager.
     */
    public function isPortalManager(): Boolean
    {
        return $this->roles->contains('label', 'is-portal-manager');
    }

    /**
     * Determine whether the current user has prime Role of Manager.
     */
    public function isManager(): Boolean
    {
        return $this->roles->contains('label', 'is-manager');
    }

    /**
     * Determine whether the current user has prime Role of Editor.
     */
    public function isEditor()
    {
        return $this->roles->contains('label', 'is-editor');
    }

    /**
     * Determine whether the current user has prime Role of Writer.
     */
    public function isWriter()
    {
        return $this->roles->contains('label', 'is-writer');
    }

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

    /**
     * Determine whether current User has the given role.
     * Given role can be a Role object or string or int
     *
     * @param Role|string|int $role
     * @return boolean
     */
    public function hasRole($role)
    {
        //dd('a');
        /** When $role is an object of class Role */
        if ($role instanceof Role) {
            return !!$role->intersect($this->roles)->count();
        }
        /** When $role is an integer */
        if (is_int(($role))) {
            return $this->roles->contains('id', $role);
        }
        /**
         * When $role is string
         *  - Check against id (in case id is uuid stored as string)
         *  - Check against name
         *  - Check against label
         */
        if (is_string($role)) {
            return !!(
                $this->roles->contains('id', $role) ||
                $this->roles->contains('name', $role) ||
                $this->roles->contains('label', $role)
            );
        }
    }

    public function hasRoleByName($role)
    {
        if ($role == null) {
            return false;
        }
        if (is_string($role)) {
            return $this->roles->contains('name', $role) || $this->roles->contains('label', $role);
        } else {
            return !!$role->intersect($this->roles)->count();
        }
    }
}

我们希望获得每个用户的所有类别(一个或多个),如下代码所示:

代码语言:javascript
复制
$user = User::find(1);
return $user->categoires();
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-27 08:32:47

您可以尝试以下特性

代码语言:javascript
复制
namespace App\Concerns;

use App\Models\Category;
use Illuminate\Database\Eloquent\Collection;

trait HasCategories
{
    /**
     * Get all Categories associated with the User in nested tree structure
     */
    public function availableCategories(): Collection
    {
        $categories = $this->categories;

        $parents = $categories->filter(fn($cat)  =>
           !in_array($cat->parent_id, $categories->pluck('id')->all()) || is_null($cat->parent_id)
        );

        $parents->map(fn($parent) => $this->setNested($parent, $categories));

        return $parents;
    }

    /**
     * Set the nested structure for the given $parent with relation.
     */
    protected function setNested($parent, $categories)
    {
        $parent->setRelation('subcategories', $categories->where('parent_id', $parent->id));
        $parent->subcategories->map(function($sub) use($categories){
            if($categories->contains('parent_id', $sub->id)) {
                $this->setNested($sub, $categories);
            }
            return $sub;
        });

        return $parent;
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65463284

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档