CakePHP извлекает данные, игнорируя 'hasMany' - PullRequest
0 голосов
/ 10 ноября 2018

У меня есть 2 таблицы - Box и Apple. Яблоко принадлежит одной коробке, а в одной коробке много яблок. В коде выглядит так:

class Apple extends AppModel {
    public $useDbConfig = 'somedb';
    public $useTable = 'apple';
    public $belongsTo = array(
        'Box' => array(
            'className' => 'Box',
            'foreignKey' => 'box_id'
        )
    );
} 
class Box extends AppModel {
    public $useDbConfig = 'somedb';
    public $useTable = 'box';
    public $hasMany = array(
        'Apple' => array(
            'className' => 'Apple',
            'foreignKey' => 'box_id',
            'dependent' => true
        )
    );
}

Когда я запрашиваю коробки: $this->Box->find("all") Я получаю список всех коробок + список всех яблок для каждой коробки:

(Array):
    [0] => (Array):
        [Box] => (Array):
            // some data
        [Apple] => (Array):
            [0] => (Array):
                // some data
            [1] => (Array):
                // some data
            ...
    [1] => (Array):
        [Box] => (Array):
            // some data
        [Apple] => (Array):
            [0] => (Array):
                // some data
            [1] => (Array):
                // some data
    ...

Итак, как я могу получить только массив ящиков без яблок?

UPDATE: Как ответил @Ben, мне нужно поставить recursive = -1 (или 0).

Но теперь у меня есть продолжение этого вопроса: если у меня есть еще одна модель - Room, комната может содержать ящики, поэтому должна быть опция $hasMany в Room для Box и $belongsTo опция для Room в Box:

 class Room extends AppModel {
    public $useDbConfig = 'somedb';
    public $useTable = 'room';
    public $hasMany = array(
        'Box' => array(
            'className' => 'Box',
            'foreignKey' => 'room_id'
        )
    );
}
// Edited Box class
class Box extends AppModel {
    public $useDbConfig = 'somedb';
    public $useTable = 'box';
    public $hasMany = array(
        'Apple' => array(
            'className' => 'Apple',
            'foreignKey' => 'box_id',
            'dependent' => true
        )
    );
    public $belongsTo = array(
        'Room' => array(
            'className' => 'Room',
            'foreignKey' => 'room_id'
        )
    );
}

Так, как я могу собрать данные о Яблоках, Ящиках и Комнатах вместе? Допустим, у меня есть условие для Room: where room.name like "room0%". Я попробовал следующее:

    $some = $this->Apple->find("all", array(
        'joins' => array(
            array('table' => 'room',
                'alias' => 'Room',
                'type' => 'INNER',
                'conditions' => array(
                    'Room.id = Box.room_id',
                )
            )
        ),
        'conditions' => array('Room.name LIKE' => 'room0%')
    ));

Но я получаю только массив пар Apple-Box.

ОБНОВЛЕНИЕ: Единственное решение, которое я сейчас нашел, это следующее:

    $temp = "room0%";
    $db = $this->Apple->getDataSource();
    $some = $db->fetchAll(
        "SELECT * 
          FROM  apple 
          JOIN box on apple.box_id = box.id
          JOIN room on box.room_id = room.id
          WHERE room.name LIKE '$temp'"
    );

Есть ли способ сделать то же самое с помощью моделей?

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Для сложных запросов на связывание рекомендуется использовать Containable . С его помощью вы можете пойти глубже , чем просто recursive = -1 в вызове модели / поиска, без ручного соединения вручную.

После настройки Containable ваш запрос может выглядеть примерно так: *

$this->Apple->find('all', array(
    'contain' => array(
        'Box' => array(
            'Room' => array(
                'conditions' => array('Room.name LIKE' => 'room0%')
            )
        )
    )
));

*) просто мой макет из памяти, не гарантированно работать как есть

0 голосов
/ 10 ноября 2018

В cakephp 2 содержимое объединяется автоматически, устанавливая recursive => -1 в вашем поисковом вызове.

...