Php Laravel过滤类别与belongtomany关联的用户
在我们的应用程序中,每个类别和用户都可以关联在一起 每个类别可以与一个或多个用户关联,每个用户可以与一个或多个类别关联 例如,假设我们有以下类别结构:Php Laravel过滤类别与belongtomany关联的用户,php,laravel,relationship,Php,Laravel,Relationship,在我们的应用程序中,每个类别和用户都可以关联在一起 每个类别可以与一个或多个用户关联,每个用户可以与一个或多个类别关联 例如,假设我们有以下类别结构: application web php laravel lumen web_design html css js mobile java
application
web
php
laravel
lumen
web_design
html
css
js
mobile
java
flutter
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)
在这个结构中,每个类别可以有一个或多个子类别,我们使用数据库结构中的parent\u id
来实现它们
现在,每个类别或与一个或多个用户关联的某些类别,例如:
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)
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)
此结构中与此用户关联的所有类别:(Alfred)
,每个类别都可以与其他用户关联,例如:
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)
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)
换句话说,你可以假设我们有这样的结构:
application
web
php
laravel
lumen
web_design
html
css
js
mobile
java
flutter
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)
这些用户属于具有角色的用户,我们将他们同步到数据库中
阿尔弗雷德:是门户网站管理员
埃拉:是经理
伊丽莎白:是经理
杰克:是编辑
斯佳丽:是作家
吉姆:是作家
我们使用category\u user
表将此结构与关联的类别和用户同步
然后我们有五个表:用户
,类别
,角色
和中间表:类别用户
和角色用户
迁移
数据库和表:
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']);
});
最后,我们的问题是什么
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)
我们希望获得与category\u user
表关联和定义的已登录用户的类别,这意味着当Alfred
登录到系统时,应具有与其关联的所有类别(一个或多个类别),其他用户应具有相同的策略
Alfred:is portal manager(所有类别都包含子类别:应用程序、web、php、laravel、lumen、web_设计、html、css、js、移动、java、Flatter)
艾拉:是经理(php、拉威尔、卢明)
Elizabeth:is经理(网页设计、html、css、js)
杰克:is编辑器(移动、java、颤振)
斯佳丽:是作家(js)
吉姆:是作家(弗利特)
完整结构:
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)
型号:
类类别扩展模型
{
公共函数父函数():BelongsTo
{
返回$this->belongsTo(类别::class,'parent_id','id','parent');
}
公共函数子类别():HasMany
{
返回$this->hasMany(Category::class,'parent_id','id');
}
公共函数users():belongtomany
{
返回$this->belongtomany(用户::类);
}
}
类角色扩展模型
{
公共函数users():belongtomany
{
返回$this->belongtomany(用户::类);
}
}
类用户扩展可验证的
{
使用应呈报文件;
/**
*获取当前用户所属的父用户。
*/
公共函数父函数():BelongsTo
{
返回$this->belongsTo(用户::类);
}
/**
*获取属于当前用户的所有用户。
*/
公共函数kids():有许多
{
返回$this->hasMany(用户::类);
}
公共函数类别():属于
{
$categories=$this->belongstomy(categories::class);
返回$categories;
}
/**
*确定当前用户是否具有门户管理器的主要角色。
*/
公共函数isPortalManager():布尔值
{
返回$this->roles->contains('label','is portal manager');
}
/**
*确定当前用户是否具有经理的主要角色。
*/
公共函数isManager():布尔值
{
返回$this->roles->contains('label','is manager');
}
/**
*确定当前用户是否具有编辑器的主要角色。
*/
公共函数isEditor()
{
返回$this->roles->contains('label','is editor');
}
/**
*确定当前用户是否具有编写器的主要角色。
*/
公共函数isWriter()
{
返回$this->roles->contains('label','is writer');
}
公共函数角色():属于
{
返回$this->belongstomy(角色::类);
}
/**
*确定当前用户是否具有给定角色。
*给定角色可以是角色对象、字符串或int
*
*@param Role | string | int$Role
*@返回布尔值
*/
公共功能hasRole($role)
{
//dd(“a”);
/**当$role是类role的对象时*/
if($role instanceof role){
return!!$role->intersect($this->roles)->count();
}
/**当$role是整数时*/
if(is_int(($role))){
返回$this->roles->contains('id',$role);
}
/**
*当$role为字符串时
*-对照id进行检查(如果id是存储为字符串的uuid)
*-核对姓名
*-对照标签检查
*/
if(is_字符串($role)){
返回(
$this->roles->contains('id',$role)||
$this->roles->contains('name',$role)||
$this->roles->contains('label',$role)
);
}
}
公共函数hasRoleByName($role)
{
如果($role==null){
返回false;
}
if(is_字符串($role)){
返回$this->roles->contains('name',$role)| |$this->roles->contains('label',$role);
}否则{
return!!$role->intersect($this->roles)->count();
}
}
}
我们希望通过以下代码为每个用户获取所有类别(一个或多个):
$user=user::find(1);
返回$user->categoires();
您可以尝试以下特性
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;
}
}
你可以试试下面的特点
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;
}
}
您是否尝试过从类别中删除()我知道添加()将返回querybuilder,tr