Laravel Eloquent 获取存储在具有角色的类别中的所有帖子

Laravel Eloquent get all Posts stored in categories with Roles

我在一个名为 CategoryUserRolePost 的数据库中有四个 table。在 Category table 中,我有一个列 category_id,在这个列中,我可以在类别中有多个 child。

每个 user belongsToMany rolescategories 以及每个 category belongsToMany posts, 我必须通过 [= 获取所有帖子27=] 登录到我们的应用程序

如您在下面的屏幕截图中所见,manager 1manager 2 属于 ToMany programingsdartflutterphp

你可以假设 manager 1 用户 id 是 1 并且 manager 22 并且他们都是 manager 角色

我的问题是如何获得 logged user belongsToMany categories 的所有帖子 role

登录用户是 manager 1,我想从 parent 中获取所有保存到类别中的帖子,即 PROGRAMINGS

例如:

$categories = Category::whereNull('category_id')->whereHas('users.roles', function($q){
    return $q->whereLabel('is-manager');
})->with(['posts' => function ($query) {
    $query->with('language');
}])->get();
dd($categories->pluck('posts'));

注意:

with @Med.ZAIRI answer which posted on this thread MANAGER 2 中未同步到 MANAGER 1 的每个用户都可以看到所有 MANAGER 1 帖子

In the Model Category add a relationship, like:

/**
* this will get the parent category
*/
public function parentCategory()
{
    return $this->belongsTo( Category::class, 'category_id', 'id' );
}

Then, try to get Posts with their categories and their parent Categories, and the users with their Roles, like:

$posts = Post::with( ['category.parentCategory', 'user.roles'])->get()

我在这个场景中使用的模型:

class Category extends Model
{
    use SoftDeletes;

    protected $guarded = ['id'];
    protected $hidden = ['id', 'category_id'];

    public function parentCategory()
    {
        return $this->belongsTo( Category::class, 'category_id', 'id' );
    }

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

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

    public function posts()
    {
        return $this->belongsToMany(Post::class);
    }

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

    public function childrenCategories()
    {
        return $this->hasMany(Category::class)->with('categories');
    }
}


class Role extends Model
{
    protected $guarded = ['id'];

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

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

    public function hasPermission($permission)
    {
        return !!$permission->intersect($this->roles->permission)->count();
    }
}


class User extends Authenticatable
{
    use Notifiable, SoftDeletes, UsersOnlineTrait;

    protected $guarded = [
        'id',
    ];
    protected $hidden = [
        'password', 'remember_token',
    ];

    protected $casts = [
        'email_verified_at' => 'datetime',
        'avatar_path' => 'array',
        'experiences' => 'array',
    ];

    public function group()
    {
        return $this->belongsToMany(UserGroup::class, 'user_user_group');
    }

    public function child()
    {
        return $this->hasMany(User::class)->with('child');
    }

    public function parent()
    {
        return $this->belongsTo(User::class, 'user_id');
    }

    public function properties()
    {
        return $this->hasOne(UsersProperty::class);
    }

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

    public function hasRole($role)
    {
        return $this->roles->contains('id', $role);
        /*if (is_string($role)) {
        } else {
            return !!$role->intersect($this->roles)->count();
        }*/
    }

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

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

}

在模型类别中添加关系,例如:

/**
* this will get the parent category
*/
public function parentCategory()
{
    return $this->belongsTo( Category::class, 'category_id', 'id' );
}

然后,尝试获取帖子及其类别及其父类别,以及用户及其角色,例如:

$posts = Post::with( ['category.parentCategory', 'user.roles'])->get()

将此添加到您的角色模型中:

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

之后您可以访问用户的帖子,例如:

$authorizedUser->roles()->with('categories.posts')->get();

您也可以将结果展平以直接访问帖子

具有为登录用户获取所有可用 post 的方法的特征 基于角色

class User extends Model
{
    use HasFactory, Notifiable, HasPosts;
}



<?php

namespace App\Concerns;

use App\Models\Category;
use Illuminate\Support\Str;
use Illuminate\Support\Collection;

trait HasPosts
{
    /**
     * Get all available posts for the currently logged in user
     *
     * @return void
     */
    public function posts()
    {
        $method = 'postsFor' . Str::studly(str_replace('is-', '', $this->roles->first()->label));

        return $this->{$method}()->collapse();
    }

    /**
     * Get all posts associated with all categories including
     * their subcategories for the logged in Portal Manager
     */
    public function postsForPortalManager(): Collection
    {
        return Category::with([
            'subcategories.posts.language', 
            'posts.language'
        ])
        ->get()
        ->pluck('posts');
    }

    /**
     * Get all posts for the logged in Manager which belong to
     * one of the categories associated with the Manager
     */
    public function postsForManager(): Collection
    {
        return $this->categories()
            ->with('posts.language')
            ->get()
            ->pluck('posts')
            ->filter(function ($collection) {
                return !!$collection->count();
            });
    }

    /**
     * Get only the posts which belong to the categories for the Editor
     * and which are authored by the logged in Editor
     */
    public function postsForEditor(): Collection
    {
        return $this->categories()
            ->with([
                'posts' => function ($query) {
                    $query->where('user_id', $this->id)->with('language');
                }, 
                'posts.language'
            ])
            ->get()
            ->pluck('posts')
            ->filter(function ($collection) {
                return !!$collection->count();
            });
    }

    /**
     * Get only the posts which belong to the categories for the Writer
     * and which are authored by the logged in Writer
     */
    public function postsForWriter(): Collection
    {
        return $this->categories()
            ->with([
                'posts' => function ($query) {
                    $query->where('user_id', $this->id)->with('language');
                }, 
                'posts.language'
            ])
            ->get()
            ->pluck('posts')
            ->filter(function ($collection) {
                return !!$collection->count();
            });
    }
}

然后对于任何经过身份验证的用户,我们可以使用

获取可用的 posts
$user->posts()

它适用于您提供的种子数据。

ella 在 Flutter 上看不到 post,而 scarlett 在 laravel

上看不到 post

这里的唯一假设是已通过身份验证的用户已担任第一个角色来查找所使用的方法。

如果你的关系都是多对多的,如下所示:

roles >-< users >-< categories >-< posts

并且都在模型中正确定义,例如

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

// User.php
public function categories()
{
    return $this->belongsToMany(Category::class);
}

// Category.php
public function posts()
{
    return $this->belongsToMany(Post::class);
}

那么我很确定你应该能够做到

$role = Role::find(1);

// get all posts from all categories from all users with $role
$posts = $role->users()->categories()->posts;