У меня 2 стола — коробка и яблоко. Яблоко принадлежит одной коробке, а в одной коробке много яблок. В коде выглядит так:
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
...
Итак, как я могу получить только массив ящиков, без яблок?
ОБНОВИТЬ:
Как ответил @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'");
Есть ли способ сделать то же самое, используя модели?
Для сложных запросов на связь желательно использовать Containable. С его помощью вы можете идти глубже чем просто recursive = -1
в модели / поиск вызова, не делая ручного соединения вручную.
После настройки Containable ваш запрос может выглядеть примерно так:
$this->Apple->find('all', array(
'contain' => array(
'Box' => array(
'Room' => array(
'conditions' => array('Room.name LIKE' => 'room0%')
)
)
)
));
*) просто мой макет из памяти, не гарантированно работать как есть
В CakePHP 2 содержание объединяются автоматически recursive => -1
в вашем поиске вызова.