Что не так с моим CakePHP HABTM Query? - PullRequest
0 голосов
/ 03 декабря 2010

У меня есть таблица Landmarks и таблица Categories с отношением HABTM друг к другу.Я пытаюсь получить все категории для определенного ориентира с помощью следующего кода:

$this->set('selected_categories', $this->Category->find('list',
    array('contain'=>array(
        'Landmarks'=>array(
           'conditions'=>array('Landmark.num'=>7)
)))));

Я проверил запрос к базе данных, который следует из этого (как напечатано на уровне отладки 2), и кажется,чтобы получить правильные результаты, то есть подмножество категорий.Однако, когда я в var_dump $ selected_categories в представлении, я получаю список ВСЕХ категорий вместо этого.

Я что-то упускаю здесь очевидное?

ETA: Я соврал, когда сказал, что вышеуказанный запрос работает.Что-то еще на странице генерирует SQL-запрос, который я хочу!Который является:

SELECT `Categories`.`num`, `CategoriesLandmark`.`category_num`,
  `CategoriesLandmark`.`landmark_num` 
FROM `categories` AS `Categories` JOIN `categories_landmarks` 
AS `CategoriesLandmark` ON (`CategoriesLandmark`.`landmark_num` = 7
AND `CategoriesLandmark`.`category_num` = `Categories`.`num`) WHERE 1 = 1

1 Ответ

1 голос
/ 03 декабря 2010

Указание типа поиска в виде 'list' несовместимо с поведением Containable.

Используйте объединения вместо этого:

$selectedCategories = $this->Category->find('list', array(
    'joins' => array(
        array(
            'table' => 'categories_landmarks',
            'alias' => 'CategoriesLandmark',
            'type' => 'inner',
            'conditions' => array("CategoriesLandmark.category_id = Category.id")
        ),
        array(
            'table' => 'landmarks',
            'alias' => 'Landmark',
            'type' => 'inner',
            'conditions' => array(
                "CategoriesLandmark.landmark_id = Landmark.id",
                'Landmark.num' => 7
            )
        ),
    )
));

В идеале я бы поместил это прямо в модель категории следующим образом:

function fetchListByLandmarkNum($landmarkNum) {
    return $this->find('list', array(
        'joins' => ...
    ));
}

А затем вызвать его из контроллера:

$selectedCategories = $this->Category->fetchListByLandmarkNum(7);
$this->set(compact('selectedCategories'));

Всегда делайте ваши модели толстыми, а контроллеры - худыми. Теперь вы можете использовать эту функцию в другом месте. :)


Причина, по которой ВСЕ категории возвращаются, заключается в том, что условие применяется к соответствующим моделям наземных ориентиров. Результатом этого Запрашиваемого запроса будет выборка всех Категорий и возврат только тех моделей Landmark, которые удовлетворяют num = 7. Он НЕ должен интерпретироваться как возвращающий только те Категории, для которых модели Landmark удовлетворяют условию.

...