Что не так с моим CakePHP HABTM Query?

0

У меня есть таблица под названием Landmarks и таблица под названием категории с отношением 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
Теги:
cakephp
has-and-belongs-to-many

1 ответ

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

Указание типа поиска как "списка" несовместимо с допустимым поведением.

Используйте присоединяется, чтобы выполнить это:

$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
            )
        ),
    )
));

Я бы идеально разместил это прямо в модели Category так:

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

И затем вызовите его с контроллера:

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

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


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

  • 0
    Да, я солгал, когда сказал, что мой запрос работает - собираюсь заново отредактировать мой вопрос. Я думаю, что я пытался изменить «список» на «все», но я обязательно попробую еще раз!
  • 0
    Я только что отредактировал свой ответ на самом деле. Попробуйте использовать соединения. Установка его на «все» также не будет работать. Буду заново редактировать мой ответ, чтобы объяснить почему.
Показать ещё 2 комментария
Сообщество Overcoder
Наверх
Меню