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