Поиск записей условий с помощью модели hasMany Cakephp3

0

У меня есть модель заказов с моделью hasMany OrderProducts. ниже мой код. Я добавил функцию поиска, используя плагин jQuery DataTable. Каждый OrderProducts содержит ref_code.

Я хочу добавить поиск, например, выбор всех ордеров, у которых есть OrderProducts, который содержит ref_code GWG-SC-001 (B) или любого другого пользователя, который вводится в поле поиска.

OrderTable.php

namespace App\Model\Table;

use Cake\ORM\Table;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\Validation\Validator;
use Cake\ORM\TableRegistry;
use Cake\I18n\Time;

class OrdersTable extends Table
{
    /**
     * Initialize method
     *
     * @param array $config The configuration for the Table.
     * @return void
     */
    public $actsAs = array('Containable');

    public function initialize(array $config)
    {
        parent::initialize($config);

        $this->table('orders');
        $this->displayField('id');
        $this->primaryKey('id');

        $this->addBehavior('Timestamp');

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

        $this->belongsTo('OrderStatus', [
            'propertyName' => 'OrderStatus',
            'foreignKey' => 'order_status_id',
            'className' => 'OrderStatus'
        ]);

        $this->hasMany('OrderProducts', [
            'className' => 'OrderProducts',
            'foreignKey' => 'order_id',
            'className' => 'OrderProducts'
        ]);


        $this->hasMany('OrderPayments', [
            'propertyName' => 'OrderPayments',
            'foreignKey' => 'order_id',
            'className' => 'OrderPayments'
        ]);


    }
}


/**
 * [getOrdersList description]
 * @param  [type] $data [description]
 * @return [type]       [description]
 */
public function getOrdersList($data, $user_id = null)
{
    $orderelem = $data['columns'][$data['order'][0]['column']]['name'];
    $ordertype = $data['order'][0]['dir'];
    $offset = $data['start'];
    $limit = $data['length'];
    $conditions = array("Orders.payment_status <>" => 0);

    if (!empty($data['search']['value'])) {
        $like = '%' . trim($data['search']['value']) . '%';
        $like2 = $data['search']['value'];
        $orValues = array("Order Received");

        if (strpos($data['search']['value'], 'Status:') !== false) {
            $data['search']['value'] = str_replace('Status: ', '', $data['search']['value']);
            $orValues = explode("|", $data['search']['value']);
        }

        $conditions[] = array(
            "Orders.payment_status <>" => 0,
            'OR' => [
                'Users.first_name LIKE' => $like,
                'Users.last_name LIKE' => $like,
                'Users.title LIKE' => $like,
                'Orders.order_number LIKE' => $like2,
                //'Orders.quantity_count LIKE'    => $like2,
                //'Orders.all_total LIKE'         => $like2,
                'Orders.tracking_number LIKE' => $like,
                'OrderStatus.title' => $like,
                'OrderProducts.ref_code' => $like, // this is not working
            ]
        );
        if (!empty($orValues)) {
            $conditions[0]['OR']['OrderStatus.title IN'] = $orValues;
        }
    }

    $data2 = $this->find('all')
        ->select([
            'id', 'order_number', 'order_type', 'created', 'tracking_number',
            'delivery_methods_id', 'order_status_id', 'quantity_count',
            'all_total', 'payment_status', 'is_allow_final_payment'
        ])
        ->contain([
            'Users' => function ($u) {
                return $u->select(['title', 'first_name', 'last_name']);

            },
            'OrderStatus' => function ($os) {
                return $os->select(['status' => 'OrderStatus.title']);
            },
            'OrderProducts'
        ]);

    if ($user_id) {
        $data2 = $data2->where(['user_id' => $user_id])->andWhere($conditions);
    } else {
        $data2 = $data2->where($conditions);
    }

    $data2 = $data2->limit($limit)
        ->order([$orderelem => $ordertype])
        ->offset($offset)
        ->toArray();

    return $data2;
}

Когда я пробую это, это дает ниже ошибку:

"message": "[PDOException] SQLSTATE [42S22]: Столбец не найден: 1054 Неизвестный столбец OrderProducts.ref_code в where where

Пожалуйста, помогите мне в этом вопросе.

ниже запрос генерирует:

SELECT
    Orders.id AS 'Orders__id',
    Orders.order_number AS 'Orders__order_number',
    Orders.order_type AS 'Orders__order_type',
    Orders.created AS 'Orders__created',
    Orders.tracking_number AS 'Orders__tracking_number',
    Orders.delivery_methods_id AS 'Orders__delivery_methods_id',
    Orders.order_status_id AS 'Orders__order_status_id',
    Orders.quantity_count AS 'Orders__quantity_count',
    Orders.all_total AS 'Orders__all_total',
    Orders.payment_status AS 'Orders__payment_status',
    Orders.is_allow_final_payment AS 'Orders__is_allow_final_payment',
    Users.title AS 'Users__title',
    Users.first_name AS 'Users__first_name',
    Users.last_name AS 'Users__last_name',
    OrderStatus.title AS 'status' 
FROM
    orders Orders 
    LEFT JOIN
        users Users 
        ON Users.id = 
        (
            Orders.user_id
        )
    LEFT JOIN
        order_status OrderStatus 
        ON OrderStatus.id = 
        (
            Orders.order_status_id
        )
WHERE
    (
        Orders.payment_status \u003C\u003E :c0 
        AND 
        (
            Orders.payment_status \u003C\u003E :c1 
            AND 
            (
                Users.first_name like :c2 
                OR Users.last_name like :c3 
                OR Users.title like :c4 
                OR Orders.order_number like :c5 
                OR Orders.tracking_number like :c6 
                OR OrderStatus.title like :c7 
                OR OrderProducts.ref_code like :c8 
                OR OrderStatus.title in 
                (
                    :c9
                )
            )
        )
    )
ORDER BY
    Orders.created desc LIMIT 25 OFFSET 25
  • 0
    ты не думаешь, что ты должен ставить like . OrderStatus.title LIKE ' => $like, 'OrderProducts.ref_code LIKE ' => $like,
  • 0
    пробовал ту же ошибку
Показать ещё 13 комментариев
Теги:
cakephp
cakephp-3.x
query-builder

1 ответ

1
Лучший ответ

Когда вы используете "содержать", он часто фактически генерирует отдельные запросы для содержащихся в них моделей. Как вы можете видеть, ваш "сгенерированный запрос" фактически не включает OrderProducts, поэтому в этом случае он генерирует отдельный запрос для OrderProducts, а затем объединяет результаты после. Из-за этого вы не можете установить условие для поля, которое не включено в запрос.

TL;DR: вместо того, чтобы содержать OrderProducts, если вы хотите добавить условия к другой модели, используйте вместо этого соединение.

В зависимости от настроек, вы можете быть в состоянии указать joinType в INNER для ассоциации.

Если нет, вы всегда можете просто ввести внутреннее соединение, как указано в книге: https://book.cakephp.org/3.0/ru/orm/query-builder.html#using-innerjoinwith

  • 0
    Внутреннее соединение сработало .. Спасибо .. !!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню