CakePHP:使用条件参数检索列表

CakePHP:使用条件参数检索列表,php,database,cakephp,Php,Database,Cakephp,我很难理解如何使用条件格式检索相关数据。 我使用的是CakePHP3.7.9 餐桌用品 表顺序 表项目订单 在另一个控制器的视图中,我有两个选择控件。第一个由现有订单的id |名称填充。当用户选择一个时,应按照以下条件填充第二个选择控件: 如果产品标识不为空->在产品表中检索名称客户代码 否则使用描述值 我使用ajax将当前订单id发送给控制器,控制器应发送回填充第二个select所需的html: 它可以正常工作,但是where子句无效。 如果没有,我将使用请求的标准从所有订单中获取所有项目。

我很难理解如何使用条件格式检索相关数据。 我使用的是CakePHP3.7.9

餐桌用品 表顺序 表项目订单 在另一个控制器的视图中,我有两个选择控件。第一个由现有订单的id |名称填充。当用户选择一个时,应按照以下条件填充第二个选择控件:

如果产品标识不为空->在产品表中检索名称客户代码 否则使用描述值 我使用ajax将当前订单id发送给控制器,控制器应发送回填充第二个select所需的html:

它可以正常工作,但是where子句无效。 如果没有,我将使用请求的标准从所有订单中获取所有项目。
当然,我只对与$id匹配的顺序感兴趣。添加where筛选器时,不会返回任何内容。

如评论中所述,您将数据作为orderId发送,但作为order\u id访问,并且您认为您使用了错误的控制器名称

您很可能在生成URL时没有收到错误,因为您正在使用或手动捕获所有路由,即类似/:controller/:action的路由,它将匹配任何控制器/操作。当向不存在的端点发出请求时,将抛出一个错误,但您尚未定义一个,因此该错误将被忽略,但您的CakePHP错误日志中应该有一些内容

也就是说,您确实不应该每行发出额外的查询,即在valueField回调中发出查询,而是在SQL级别(例如使用)进行过滤,或者包含产品关联,这样您就拥有了在PHP级别进行过滤所需的所有数据,这应该非常简单:

$items=$this->ItemsDeliveryNotes->Orders->itemsorders ->查找“列表”[ “keyField”=>“id”, 'valueField'=>function\Cake\Datasource\EntityInterface$row{ 如果$row->有“产品”{ 返回$row->product->name.'.$row->product->客户代码; } 返回$row->description; } ] ->包含“产品” ->在哪里[ “订单id”=>$id ];
您正在发送orderId,但正在访问order_id。也就是说,应该避免每行发出额外的查询,在SQL级别进行过滤,或者包含产品关联,然后在PHP级别进行过滤。我对PHP和CakePHP不熟悉。请你给我一个更详细的答复好吗?我不完全理解你的建议。事实上,问题是另一个输入错误:“控制器”=>“ItemDeliveryNotes”而不是ItemsDeliveryNotes。有了这个修正,它就工作了。奇怪的是,它没有引发错误。两个版本的代码都返回相同的结果。你说:你真的不应该每行发出额外的查询。你能解释一下原因吗?我只是想了解潜在的问题。@Mark,因为这只是不必要的开销,可以很容易地避免。您的示例看起来每个检索到的行至少会发出2个查询,我假设field方法查询数据库,因此如果您的list finder查询将检索100个项目订单,它将发出至少200个额外的查询。
id
name
customer_code
id
name
date
id
order_id
name
product_id
description
<?php $this->Html->scriptStart(['block' => 'script', 'inline' => false]); ?>
    $(document).on('change', '#order-id', function() {
        $.ajax({
            type: "POST",
            headers: { 'X-CSRF-Token': <?= json_encode($this->request->getParam('_csrfToken')); ?> },
            url:  '<?php echo Router::url(array('controller' => 'ItemDeliveryNotes', 'action' => 'getOrderItems'));?>',
            data: { 'orderId': $('#order-id').val() },
            success: function(response) {
                $('#itemOrders').html(response.data.itemOrders);
            }
        });
    });
<?php $this->Html->scriptEnd(); ?>

public function getOrderItems()
{
    if ($this->request->is(['ajax', 'post']))
    {
        $id = $this->request->getData('orderId'); // <-- fixed
        $items = $this->getItems($id);
        $combo = [];
        foreach ($items as $key => $value)
        {
            $combo[] = "<option value='" . $key . "'>" . $value . "</option>";
        }

        $data = ['data' => ['itemOrders' => $combo]];
        return $this->json($data);
    }
}

private function getItems($id = null)
{
    $items = ???; // <-- here I need to retrieve the list as above
    return $items;
}
private function getItems($id = null)
{
    $items = $this->ItemsDeliveryNotes->Orders->ItemOrders->
        find('list', [
            'keyField' => 'id',
            'valueField' => function ($q) {
                $productId = $q->get('product_id');
                if ($productId) {
                    $code = $this->ItemsDeliveryNotes->Orders->ItemOrders->Products->field('code', ['id' => $productId]);
                    $customerCode = $this->ItemsDeliveryNotes->Orders->ItemOrders->Products->field('customerCode', ['id' => $productId]);
                    return $code . ' (' . $customerCode . ')';
                }
                else return $q->get('description');
            }
        ])->where(['order_id' => $id]);
    return $items;
}