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
控件应按照以下标准填充:
- 如果
product_id
不为空 -> 在 products
table 中检索 name (customer_code)
- 否则使用
description
值
我使用 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
]);
我很难理解如何使用条件格式检索关联数据。 我正在使用 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
控件应按照以下标准填充:
- 如果
product_id
不为空 -> 在products
table 中检索 - 否则使用
description
值
name (customer_code)
我使用 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
]);