在我们的应用程序中,每个类别和用户可以关联在一起。
每个类别可以与一个或多个用户关联,每个用户可以关联一个或多个类别。
例如,假设我们有这样的类别结构:
application
web
php
laravel
lumen
web_design
html
css
js
mobile
java
flutter在这种结构中,每个类别可以是一个或多个子类,我们在数据库结构中使用parent_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)此结构中与此用户关联的所有类别:(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 (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)这个用户是BelongsToMany和Role,我们将它们同步到数据库中。
阿尔弗雷德:is-portal-manager
我们使用category_user表来同步此结构以关联类别和用户。
然后我们有五个表:users、categories、roles和中间表:category_user和role_user
migrations数据库和表:
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)
完全结构
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)型号:
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();
}
}
}我们希望获得每个用户的所有类别(一个或多个),如下代码所示:
$user = User::find(1);
return $user->categoires();发布于 2020-12-27 08:32:47
您可以尝试以下特性
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;
}
}https://stackoverflow.com/questions/65463284
复制相似问题