【问题标题】:How to query associations using an alias in CakePHP?如何在 CakePHP 中使用别名查询关联?
【发布时间】:2021-06-23 10:30:51
【问题描述】:

我在 CakePHP 3 中有以下查询,用于对任务实体进行搜索:

<?php

    public function search($q = "")
    { 
        $tasks = TableRegistry::getTableLocator()->get('Tasks')->find()
            ->where(function (QueryExpression $exp, Query $query) use ($q) {
                return $exp->or_(function (QueryExpression $or) use ($query, $q) {
                    $or->like('Tasks.name', '%' . $q . '%');
                    $or->like('Asset.name', '%' . $q . '%');
                    $or->like('AssignedToUsers.first_name', '%' . $q . '%');
                    $or->like('AssignedToUsers.last_name', '%' . $q . '%');
                    $or->like($query->func()->concat([
                        'AssignedToUsers.first_name' => 'identifier',
                        "' '" => 'literal',
                        'AssignedToUsers.last_name' => 'identifier'
                    ]), '%' . $q . '%');
                    return $or;
                });
            })
            ->contain(["Asset", "Asset.AssignedToUsers", "AssignedToUsers"])
            ->limit(5)
            ->order(["Tasks.modified" => "DESC"]);
    }

Task 表与 Asset 和 AssignedToUsers 表关联如下:

<?php

public function initialize(array $config)
{
    $this->belongsTo('Asset', [
        'className' => 'Assets',
        'foreignKey' => 'asset_id',
        'joinType' => 'LEFT'
    ]);
    $this->belongsTo('AssignedToUsers', [
        'className' => 'Users',
        'foreignKey' => 'assigned_to_user_id',
        'joinType' => 'LEFT'
    ]);
}

然后 Asset 表也有一个 AssignedToUsers 关联:

<?php

public function initialize(array $config)
{
    $this->belongsTo('AssignedToUsers', [
        'className' => 'Users',
        'foreignKey' => 'assigned_to_user_id',
        'joinType' => 'LEFT'
    ]);
}

当前查询对 AssignedToUsers 的名字和姓氏进行串联搜索。但是我需要让它包括搜索 Asset.AssignedToUsers 的名字和姓氏。

如果我从搜索中的包含中删除了 AssignedToUsers 关联,则查询将搜索 concat 中的 Asset.AssignedToUsers 名字和姓氏字段,因此我假设 cake 无法区分 AssignedToUsers 和 Asset 之间的区别。分配给用户。

有没有一种方法可以在 contains() 调用中为两个 AssignedToUsers 关联设置别名,以便我可以分别查询与 Task 和 Asset 关联的版本 AssignedToUsers?还是有其他方法可以执行此查询?

提前致谢!

【问题讨论】:

    标签: php cakephp cakephp-3.0


    【解决方案1】:

    您不能在单个查询中多次使用同一个别名,这首先是 SQL 限制,最后是 CakePHP 不支持。也不支持即时更改别名。

    对于包含数据,您可以尝试不同的策略,特别是 select 策略,它将在单独的查询中检索关联的数据,而不是将其加入。对于过滤,您可以使用带有自定义别名的自定义联接,大致如下:

    ->where(function (QueryExpression $exp, Query $query) use ($q) {
        return $exp->or_(function (QueryExpression $or) use ($query, $q) {
            // ...
            $or->like(
                $query->func()->concat([
                    'AssetAssignedToUsers.first_name' => 'identifier',
                    "' '" => 'literal',
                    'AssetAssignedToUsers.last_name' => 'identifier'
                ]),
                '%' . $q . '%'
            );
            
            return $or;
        });
    })
    ->join([
        'table' => 'users',
        'alias' => 'AssetAssignedToUsers',
        'type' => 'LEFT',
        'conditions' => 'AssetAssignedToUsers.id = Asset.assigned_to_user_id',
    ])
    ->contain([
        'Asset',
        'Asset.AssignedToUsers' => [
            'strategy' => \Cake\ORM\Association::STRATEGY_SELECT,
        ],
        'AssignedToUsers',
    ])
    

    另一种选择是重命名一个,甚至所有关联,例如在它们前面加上父名称,如TasksAssignedToUsersAssetAssignedToUsers 等。

    另见

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-23
      • 1970-01-01
      相关资源
      最近更新 更多