CakePHP 3具有很多与按位表达式的关联

时间:2018-09-11 20:12:14

标签: cakephp associations cakephp-3.x

我有两个表AclGroups和AclPermissions,我想在它们之间创建hasMany关系,即AclGroups有许多AclPermissions。

确定组是否拥有给定权限的条件是通过单个按位检查完成的。这就是我想要做的:

SELECT 
    *
FROM
    acl_groups
        JOIN
    acl_permissions ON acl_permissions.permission & acl_groups.permission != 0

AclGroupsTable中,我尝试了以下操作:

$this->hasMany('AclPermissions', [
    'className' => 'AclPermissions',
    'foreignKey' => 'permission',
    'conditions' => [
        'AclPermissions.permission & AclGroups.permission !=' => 0
    ]
]);

但是那给了我 SQLSTATE[42S22]: Column not found: 1054 Unknown column 'aclgroups.permission' in 'where clause'

在我的控制器中,我这样做:

$this->AclGroups->find('all')->contain(['AclPermissions']);

我认为真正的问题是:有没有一种方法可以更改获取关联记录的查询中ON子句的条件

1 个答案:

答案 0 :(得分:0)

如评论中所述,在使用hasMany时,将始终在单独的查询中检索belongsToMany关联的记录(与此相关的contain())。

如果您需要使用这种关联创建联接,则必须显式使用相应的联接功能,例如leftJoinWith()

$this->AclGroups->find('all')->leftJoinWith('AclPermissions');

这将创建与您所显示的查询类似的查询。但是,它还会使用配置的外键生成默认条件,您必须禁用外键以避免这种情况,例如:

$this->hasMany('AclPermissions', [
    'foreignKey' => false, // << like this
    // ...
]);

鉴于关联条件不适用于contain()(并且禁用外键将使其更加无法用于该目的),您可能想要创建单独的关联以用于联接目的,或使用“较低级别”的连接方法,您可以在其中手动指定所有条件(例如,可以将其放在自定义查找器中,以使代码保持DRY):

$query = $this->AclGroups
    ->find('all')
    ->join([
        'table' => 'acl_permissions',
        'alias' => 'AclPermissions',
        'type' => 'LEFT',
        'conditions' => [
            'AclPermissions.permission & AclGroups.permission != :permission'
        ]
    ])
    ->bind(':permission', 0, 'integer');

请注意,此处已明确绑定该值以确保使用正确的类型,因为无法从非标准的左手值(实际上并不包含SQL代码段)确定该值可能想研究使用表达式)。

另请参见