【问题标题】:How to Filter Associated Data using FriendsOfCake Search plugin for CakePHP 3.1.0如何使用适用于 CakePHP 3.1.0 的 FriendsOfCake 搜索插件过滤关联数据
【发布时间】:2021-03-18 22:32:26
【问题描述】:

插件:FriendsOfCake\Search

CakePHP: 3.1.0

我目前正在添加在index() 方法上过滤我的订单控制器的功能。我需要能够在下订单的用户的姓名中搜索订单。每个订单都与Users 模型相关联:

    $this->belongsTo('Users', [
        'foreignKey' => 'user_id',
        'joinType' => 'INNER'
    ]);

当我在OrdersTable.php 文件中构建我的searchConfiguration() 方法时,我有以下内容:

    ->value('first_name', [
        'field' => $this->aliasField('Users.first_name')
    ])
    ->value('last_name', [
        'field' => $this->aliasField('Users.last_name')
    ])

Orders index() 方法

    $query = $this->Orders->find('search', 
        $this->Orders->filterParams($this->request->query))->contain(['Users', 'PaymentMethods', 'Industries']
    )->order(['Orders.created' => 'DESC']);
    $this->set('orders', $this->paginate($query));

当我没有向查询传递任何参数时,这加载正常,但是,一旦我尝试通过first_namelast_name 进行搜索,我就会收到错误:

错误:SQLSTATE[42S22]:找不到列:1054 'where 子句'中的未知列'Orders.Users.first_name'

根据错误,它正在附加订单。到我要搜索的字段。据我所知CakePHP 有两种方法aliasField() 一种在\var\www\<project_name>\vendors\cakephp\cakephp\src\ORM\Query.php

public function aliasField($field, $alias = null)
{
    $namespaced = strpos($field, '.') !== false;
    $aliasedField = $field;

    if ($namespaced) {
        list($alias, $field) = explode('.', $field);
    }

    if (!$alias) {
        $alias = $this->repository()->alias();
    }

    $key = sprintf('%s__%s', $alias, $field);
    if (!$namespaced) {
        $aliasedField = $alias . '.' . $field;
    }

    return [$key => $aliasedField];
}

还有一个\var\www\<project_name>\vendors\cakephp\cakephp\src\ORM\Table.php

public function aliasField($field)
{
    return $this->alias() . '.' . $field;
}

看来Query.php 将允许您为该字段指定$alias,但是,Table.php 不允许,所以我认为这就是这里使用的方法。

谁能指导我如何过滤关联表中包含的数据?

【问题讨论】:

    标签: php cakephp cakephp-3.1


    【解决方案1】:

    当您已经提供别名时,不要使用aliasField()

    'field' => 'Users.first_name'
    

    或在关联的Users 表上使用aliasField()

    'field' => $this->Users->target()->aliasField('first_name')
    

    使用Query::aliasField() 是完全错误的,因为这将返回一个key => value 数组以供Query::select() 使用。

    【讨论】:

    • 使用上面的代码效果很好。我确实有2个问题。 1.当我第一次修改我的代码时,我将 ->target() 排除在外,它也可以正常工作,target() 方法提供了什么目的? 2. 您提到在提供别名时不使用 aliasField(),我该如何编码?
    • @hulk66049 1.) 使用target() 更具体。它也可以在没有的情况下工作,因为在内部关联类(Users 属性确实 持有表类实例!)会将未知方法调用委托给target()using a magic __call() handler。 2.)查看我的更新答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-04
    • 1970-01-01
    • 2012-03-04
    • 1970-01-01
    • 2014-05-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多