gpt4 book ai didi

php - 我可以使用同一张表以不同方式/以更 Cake 的方式重构我的多个用户类型的设置吗?

转载 作者:可可西里 更新时间:2023-11-01 12:35:20 27 4
gpt4 key购买 nike

我有一个 my_users 表,现在我需要通过删除 role 列来重构它,以支持每个用户支持多个角色。例如,我正在处理的 3 种用户类型是:

  1. 斗士
  2. 裁判
  3. 经理

所以表格设置如下所示:

Users.php

use CakeDC\Users\Model\Table\UsersTable as BaseUsersTable;

class UsersTable extends BaseUsersTable
{
public function initialize(array $config)
{
parent::initialize($config);

$this->setEntityClass('Users\Model\Entity\User');

$this->belongsToMany('UserRoles', [
'through' => 'users_user_roles'
]);

$this->hasMany('UsersUserRoles', [
'className' => 'Users.UsersUserRoles',
'foreignKey' => 'user_id',
'saveStrategy' => 'replace',
]);
}

public function findRole(Query $query, array $options)
{
return $query
->innerJoinWith('UserRoles', function($q) use ($options) {
return $q->where(['role_key' => $options['role_key']]);
});
}
}

MyUsersTable.php

class MyUsersTable extends Table
{
public function initialize(array $config)
{
parent::initialize($config);

$this->setTable('my_users');

$this->setPrimaryKey('user_id');

$this->belongsTo('Users', [
'className' => 'Users.Users',
'foreignKey' => 'user_id',
]);
}

/**
* @param Cake\Event\Event $event
* @param Cake\ORM\Query $query
* @param ArrayObject $options
*/
public function beforeFind(Event $event, Query $query, \ArrayObject $options)
{
// set the role
if (defined(static::class.'::ROLE') && mb_strlen(static::ROLE) > 0) {
$role = static::ROLE;

// set user conditions
$query->innerJoinWith('Users', function($query) use ($role) {
return $query->find('role', [
'role_key' => $role,
]);
});
}
}

/**
* @param \Cake\ORM\Query $query
* @param array $options
*/
public function findByRegistrationCode(Query $query, array $options): Query
{
$query->where([
$this->aliasField('registration_no') => $options['registration_no']
]);

return $query;
}
}

FightersTable.php

use MyUsers\Model\Table\MyUsers;

class FightersTable extends MyUsersTable
{
const ROLE = 'fighter';

public function initialize(array $config)
{
parent::initialize($config);

$this->setEntityClass('Fighters\Model\Entity\Fighter');
}

/**
* @param Validator $validator
* @return Validator $validator
*/
public function validationDefault(Validator $validator): Validator
{
$validator = parent::validationDefault($validator);

$validator->allowEmpty('field');
}
}

RefereesTable.phpManagersTable.php 类似于 FightersTable 但有自己的验证规则,可能有自己特殊的实体虚拟属性什么不是。

问题:有没有更简单的方法来构建它,或者更具体地说,有一种替代方法来执行 beforeFind 来区分角色?如果对 role 的要求与用户保持 1:1 的比例,我可能会做这样的事情:

$this->belongsTo('Fighters', [
'conditions' => [
'role' => 'fighter'
],
'foreignKey' => 'user_id',
'className' => 'MyUsers',
]);

我将不胜感激任何关于重构它的见解。

最佳答案

您可以定义belongsTo 关联以使用findByRole finder :

 $this->belongsTo('Fighters', [
'foreignKey' => 'user_id',
'className' => 'MyUsers',
'finder' => ['byRole' => ['role' => 'fighter']]
]);

当然,您必须在 MyUsers 中定义查找器:

public function findByRole(Query $query, \ArrayObject $options)
{
$role = $options['role'];

// set user conditions
$query->innerJoinWith('Users', function($query) use ($role) {
return $query->find('role', [
'role_key' => $role,
]);
});
}
}

我还会将 beforeFind 逻辑提取到 RoleBehaviorMultiRoleBehavior behavior , IE。:src/Model/Behavior/RoleBehavior.php:

<?php
namespace App\Model\Behavior;

use Cake\ORM\Behavior;
use Cake\ORM\Query;
use Cake\Event\Event;

/**
* Role-specific behavior
*/
class RoleBehavior extends Behavior
{

/**
* @var array multiple roles support
*/
protected $_defaultConfig = [
'roles' => []
];


public function initialize(array $config)
{
parent::initialize($config);
if (isset($config['roles'])) {
$this->config('roles', $config['roles'], false /* override, not merge*/);
}
}

public function beforeFind(Event $event, Query $query, \ArrayObject $options, $primary) {
// set user conditions
$query->innerJoinWith('Users', function($query) use ($roles) {
return $query->find('role', [
'role_key' => $roles,
]);
});
}
}

它使用多个角色,但如果需要,您可以简单地将其更改为单个角色。这里还有一些其他要做的事情——可能将 $query->innerJoinWith('Users'... 提取到行为中的一个单独的方法中,并在 MyUsers::findByRole(. ..)...

接下来,您可以将此行为直接附加到扩展类中,只需将静态 ROLE 替换为行为配置即可:

use MyUsers\Model\Table\MyUsers;

class FightersTable extends MyUsersTable
{
public function initialize(array $config)
{
parent::initialize($config);

$this->setEntityClass('Fighters\Model\Entity\Fighter');

$this->addBehavior('Role', [ 'roles' => ['fighter']]);
}
}

或者您可以通过将行为附加到 MyUsers 表(即来自 Controller )来管理特定于角色的逻辑:

$this->MyUsers->addBehavior('Role', ['roles' => ['manager']])

You also can change the behavior setup on the fly :

$this->MyUsers->behaviors()->get('Role')->config([
'roles' => ['manager'],
]);

希望对你有帮助。

关于php - 我可以使用同一张表以不同方式/以更 Cake 的方式重构我的多个用户类型的设置吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49799073/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com