Cake PHP 3: -> find ('all') с содержанием, не заполняемым связанными данными - PullRequest
0 голосов
/ 31 марта 2020

Я пытаюсь ->find('all') и содержать hasMany () Расписания, которые serveTo () Службы в методе индекса контроллера служб. Сервис может фактически иметь от нуля до многих расписаний. Тестирование и опыт использования метода представления служб привели меня к мысли, что проблема связана с полем БД, в котором используется ключевое слово. Это область, в которой я не вижу необходимости в настоящее время. К сожалению, у меня нет возможности изменить структуру базы данных.

Я попытался ->contain() и указал нужные мне поля, включая основные поля, содержащиеся в расписаниях. Результаты были такими же, как попытка № 1, перечисленная ниже. Я успешно использовал это в другой модели.

Я пытался ->selectAllExcept($tableObj, ['FieldToExclude'])->contain(). Я также пытался выполнить beforeFind () в SchedulesTable. php после исследования здесь , но функция никогда не вызывалась.

Я могу обойти проблему в методе view указав поля в находке непосредственно в таблице служб. Тем не менее, это не жизнеспособный вариант в методе индекса. Я могу сделать все 1055 *, чтобы получить соответствующие записи, но это своевременно и побеждает фантастические преимущества Cake. Контейнер - это круто, и это именно то, что мне нужно.

Неправильно ли настроены ownTo & hasMany? Я что-то упустил в коде $ query? Я прочитал документацию и знаю, что мне не хватает того, что, вероятно, очевидно для многих. Я знаю, что дошел до разочарования, которое не позволяет мне думать ясно. ;) Я даже отошел на день, надеясь, что это поможет.

Заранее благодарю за любую помощь, которая может быть оказана. Это будет высоко оценено.

ServicesTable. php

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

    $this->setTable('OSCL');
    $this->setDisplayField('DocNum');
    $this->setPrimaryKey('DocNum');
    $this->belongsTo('Locations', [
                                    'className' => 'Locations', 
                                    'bindingKey' => 'Address', 
                                    'foreignKey' => 'BPShipCode',
                                    'joinType' => 'INNER'
                                ]
                    );
    $this->hasMany('Schedules', [
                                    'className' => 'Schedules', 
                                    'foreignKey' => 'SrcvCallID', 
                                    'bindingKey' => 'CallID'
                                ]
                );
}

и SchedulesTable. php

use Cake\Event\Event;
use ArrayObject;

class SchedulesTable extends Table
{   
    public function initialize(array $config)
    {
        parent::initialize($config);

        $this->setTable('SCL6');
        $this->setDisplayField('Technician'); 
        $this->setPrimaryKey(['SrcvCallID', 'Line']);
        $this->belongsTo('Services', [
                                    'className' => 'Services', 
                                    'foreignKey' => 'SrcvCallID', 
                                    'bindingKey' => 'CallID'
                                ]
                    );
    $this->hasOne('Employees', [
                                'className' => 'Employees', 
                                'foreignKey' => 'empID', 
                                'bindingKey' => 'Technician'
                            ]
                    );

    }

    /*
     Added to class after the original 3 attempts.
     Re-attempted the queries. Function made no difference.
     Debug & die within the function showed that the function was never called.
    */
    public function beforeFind(Event $event, Query $query, ArrayObject $options, $primary)
    {
        return $query->selectAllExcept($this, ['Close']);
    }
}

Попытка # 1 возвращает ожидаемое количество записей но массив расписаний пуст. Я не получаю никаких сообщений об ошибках, и журнал запросов не показывает никаких попыток доступа к таблице расписаний.

$query = $this->Services->find('all')
                        ->where($conditions)
                        ->order([$sort => $direction])
                        ->contain(['Schedules']);

Отладка $ query-> toArray (); В таблице более 100 полей. Здесь я удалил многие из них для наглядности.

\src\Controller\ServicesController.php (line 124)
[
    (int) 0 => object(App\Model\Entity\Service) {

        'callID' => (int) 361893,
        'subject' => 'Printer jam',
        'customer' => 'C202044',
        'custmrName' => 'Some Company',
        'contctCode' => (int) 986,
        'manufSN' => '',
        'internalSN' => '16J151800861',
        'createDate' => object(Cake\I18n\FrozenTime) {

            'time' => '2020-03-17 00:00:00.000000-04:00',
            'timezone' => 'America/New_York',
            'fixedNowTime' => false

        },
        'createTime' => (int) 1612,
        'closeDate' => null,
        'closeTime' => null,
        'DocNum' => (int) 316939,
        'Series' => (int) 30,
        'schedules' => [],
        '[new]' => false,
        '[accessible]' => [],
        '[dirty]' => [],
        '[original]' => [],
        '[virtual]' => [],
        '[hasErrors]' => false,
        '[errors]' => [],
        '[invalid]' => [],
        '[repository]' => 'Services'
    },
]

Журнал запросов

SELECT 
    Services.callID AS [Services__callID], Services.subject AS [Services__subject], Services.customer AS [Services__customer], Services.custmrName AS [Services__custmrName], ... 
FROM 
    OSCL Services 
WHERE 
    (
        Services.status = 7 
        OR Services.status = -3
    ) 
ORDER BY Services.DocNum DESC OFFSET 0 ROWS FETCH FIRST 20 ROWS ONLY

SELECT 
  (
    COUNT(*)
  ) AS [count] 
FROM 
  OSCL Services 
WHERE 
  (
    Services.status = 7 
    OR Services.status = -3
  )

При попытке # 2 генерируется ошибка запроса SQL Ошибка: SQLSTATE [42000] : [Microsoft] [ODB C Драйвер 17 для SQL Сервер] [SQL Сервер] Неверный синтаксис рядом с ключевым словом «Закрыть» ». Имеет смысл, потому что поведение модели по умолчанию - выбрать все поля.

$query = $this->Services->find('all')
                        ->where($conditions)
                        ->order([$sort => $direction])
                        ->select($this->Services->Schedules);

Попытка # 3. Я попытался передать объект таблицы -> selectAllExcept () и исключить проблемное поле. Построитель запросов неправильно строит запрос, используя поля из таблицы расписаний, как если бы они были частью таблицы служб

$query = $this->Services->find('all')
                        ->where($conditions)
                        ->order([$sort => $direction])
                        ->selectAllExcept($this->Services->Schedules, ['Close'])
                        ->contain(['Schedules']);

Запрос, построенный построителем запросов. SrcvCallID, Line & Technician - это все поля таблицы Расписаний, а не Службы.

SELECT 
    Services.SrcvCallID AS [Services__SrcvCallID], Services.Line AS [Services__Line], Services.Technician AS [Services__Technician], ... 
FROM 
    OSCL Services 
WHERE 
    (Services.status = :c0 OR Services.status = :c1) 
ORDER BY 
    Services.DocNum DESC 
OFFSET 0 ROWS FETCH FIRST 20 ROWS ONLY

Вот пример ожидаемых результатов , созданных вручную из функции представления.

[
    (int) 0 => object(App\Model\Entity\Service) {

        'callID' => (int) 361893,
        'subject' => 'Printer jam',
        'customer' => 'C202044',
        'custmrName' => 'Some Company',
        'contctCode' => (int) 986,
        'manufSN' => '',
        'internalSN' => '16J151800861',
        'createDate' => object(Cake\I18n\FrozenTime) {

            'time' => '2020-03-17 00:00:00.000000-04:00',
            'timezone' => 'America/New_York',
            'fixedNowTime' => false

        },
        'createTime' => (int) 1612,
        'closeDate' => null,
        'closeTime' => null,
        'DocNum' => (int) 316939,
        'Series' => (int) 30,
        'schedules' => [
        (int) 0 => object(App\Model\Entity\Schedule) {

            'SrcvCallID' => (int) 361893,
            'Line' => (int) 1,
            'Technician' => (int) 243,
            'StartDate' => object(Cake\I18n\FrozenTime) {

                'time' => '2020-03-18 00:00:00.000000-04:00',
                'timezone' => 'America/New_York',
                'fixedNowTime' => false

            },
            'StartTime' => (int) 800,
            'EndDate' => object(Cake\I18n\FrozenTime) {

                'time' => '2020-03-18 00:00:00.000000-04:00',
                'timezone' => 'America/New_York',
                'fixedNowTime' => false

            },
            'EndTime' => (int) 900,
            'U_NB_ChkInDate' => null,
            'U_NB_ChkInTime' => null,
            'U_NB_ChkOutDate' => null,
            'U_NB_ChkOutTime' => null,
            'SignData' => null,
            'Duration' => (float) 1,
            'DurType' => 'H',
            'Sched_Closed' => 'N',
            'U_NB_TechRate' => (float) 50,
            'U_NB_FollowUp' => null,
            '[new]' => false,
            '[accessible]' => [],
            '[dirty]' => [],
            '[original]' => [],
            '[virtual]' => [],
            '[hasErrors]' => false,
            '[errors]' => [],
            '[invalid]' => [],
            '[repository]' => 'Schedules'

        },
        (int) 1 => object(App\Model\Entity\Schedule) {

            'SrcvCallID' => (int) 361893,
            'Line' => (int) 2,
            'Technician' => (int) 243,
            'StartDate' => object(Cake\I18n\FrozenTime) {

                'time' => '2020-03-17 00:00:00.000000-04:00',
                'timezone' => 'America/New_York',
                'fixedNowTime' => false

            },
            'StartTime' => (int) 1600,
            'EndDate' => object(Cake\I18n\FrozenTime) {

                'time' => '2020-03-17 00:00:00.000000-04:00',
                'timezone' => 'America/New_York',
                'fixedNowTime' => false

            },
            'EndTime' => (int) 1630,
            'U_NB_ChkInDate' => object(Cake\I18n\FrozenTime) {

                'time' => '2020-03-17 00:00:00.000000-04:00',
                'timezone' => 'America/New_York',
                'fixedNowTime' => false

            },
            'U_NB_ChkInTime' => (int) 1600,
            'U_NB_ChkOutDate' => object(Cake\I18n\FrozenTime) {

                'time' => '2020-03-17 00:00:00.000000-04:00',
                'timezone' => 'America/New_York',
                'fixedNowTime' => false

            },
            'U_NB_ChkOutTime' => (int) 1630,
            'SignData' => null,
            'Duration' => (float) 30,
            'DurType' => 'M',
            'Sched_Closed' => 'N',
            'U_NB_TechRate' => (float) 150,
            'U_NB_FollowUp' => 'Y',
            '[new]' => false,
            '[accessible]' => [],
            '[dirty]' => [],
            '[original]' => [],
            '[virtual]' => [],
            '[hasErrors]' => false,
            '[errors]' => [],
            '[invalid]' => [],
            '[repository]' => 'Schedules'

        }
    ],
        '[new]' => false,
        '[accessible]' => [],
        '[dirty]' => [],
        '[original]' => [],
        '[virtual]' => [],
        '[hasErrors]' => false,
        '[errors]' => [],
        '[invalid]' => [],
        '[repository]' => 'Services'
    },
]

Опять же, спасибо за любую помощь.

...