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

CakePHP: retrieve list with conditional arguments

我很难理解如何使用条件格式检索关联数据。 我正在使用 CakePHP 3.7.9。

Table 产品

id
name
customer_code

Table 订单

id
name
date

Table item_orders

id
order_id
name
product_id
description

在(另一个控制器的)视图中,我有两个 select 控件。第一个填充了 id|name 个现有订单。当用户选择一个时,第二个 select 控件应按照以下标准填充:

我使用 ajax 将当前 order_id 发送到控制器,该控制器应该发回填充第二个 select 所需的 html:

<?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;
}

它工作正常,但 where 子句。 没有,我使用请求的标准从所有订单中获取所有项目。 但当然我只对匹配 $id 的顺序感兴趣。添加 where 过滤器,没有返回任何内容。

如评论中所述,您以 orderId 的形式发送数据,但以 order_id 的形式访问数据,而且您认为您还使用了错误的控制器名称。

你很可能在生成 URL 时没有收到错误,因为你正在使用 fallbacks, or manual catch-all routes, that is routes like /:controller/:action, which will match any controller/action. An error will be thrown when the request is being made to the non-existent endpoint, but you haven't defined an error/failure handler for your AJAX call,所以错误被吞没了,你的 Cake[=25] 中应该还有一些东西=] 错误日志。

也就是说,您真的不应该每行发出额外的查询(即在 valueField 回调中发出查询),而是在 SQL 级别进行过滤,例如使用 CASE expression,或包含 Products 关联,以便您拥有在 PHP 级别过滤所需的所有数据,这应该很简单:

$items = $this->ItemsDeliveryNotes->Orders->ItemOrders
    ->find('list', [
        'keyField' => 'id',
        'valueField' => function (\Cake\Datasource\EntityInterface $row) {
            if ($row->has('product')) {
                return $row->product->name . ' (' . $row->product->customer_code . ')';
            }

            return $row->description;
        }
    ])
    ->contain('Products')
    ->where([
        'order_id' => $id
    ]);