2013-05-08 1 views
1

Я ищу самый простой способ поиска в разных моделях одновременно. У меня есть 3 модели: игра, фильм и книга, и я хочу иметь возможность искать название игры, фильма или книги в одном запросе. Кто-нибудь знает легкое решение? Это простая задача без использования плагинов?Как искать различные модели одновременно в CakePHP?

Благодаря

ответ

2

Просто запрос одну модель, а затем следующий, затем следующий.

Если модели не связаны друг с другом, нет возможности вернуть результаты от всех из них в одном запросе - это ограничение SQL, а не CakePHP (EDIT - не так, вы можете использовать UNION operator). И, конечно же, нет способа позвонить в три модели в одну строку или что угодно.

Итак, просто сделайте три отдельных запроса, а затем сделайте все, что хотите, с результатами. Вы можете отображать их отдельно или объединять их в один массив и повторно сортировать, а затем отображать их вместе - все, что щекочет вас.

EDIT (после того, как мой ответ был уже принят как правильно!):

Как @xgalvin упоминалось, вы можете объединить несколько таблиц в 1 заявление, используя UNION operator. Итак, я ошибся. Но если разные таблицы не очень похожи, то оператор UNION, вероятно, не подходит, и вам все равно лучше делать 3 запроса. Если все, что вы хотите, это id, имя и тип, то ответ @ xgalvin лучше моего.

+0

Спасибо за обновление! «UNION» имеет довольно ограниченное использование, но он должен быть немного быстрее, чем три запроса и слияние их с PHP, предполагая, что схема трех таблиц аналогична. –

2

Без отношения между ними, в одном find() заявление? No.

Вы можете сделать что-то вроде этого:

$models = array('Game', 'Movie', 'Book'); 
$search = 'some title'; 
$results = array(); 

foreach($models as $model) { 
    $this->loadModel($model); 
    $results[$model] = $this->{$model}->find('all', array('conditions' => array($model . '.title' => $search))); 
} 
2

включают в себя следующие в любой модели (позволяет сказать, что средства массовой информации для данного примера):

public function search($query) { 
    $query = Sanitize::clean($query); 
    $result = $this->query(" 
     (SELECT id, name, 'book' AS type FROM books WHERE name LIKE '%$query%') 
     UNION ALL 
     (SELECT id, name, 'movie' AS type FROM movies WHERE name LIKE '%$query%') 
     UNION ALL 
     (SELECT id, name, 'game' AS type FROM games WHERE name LIKE '%$query%') 
    "); 
    $result = Hash::extract($result, "{n}.{n}"); 
    return $result; 
} 

'book' AS type часть может быть удалена, если у вас есть другой способ идентификации типа элемента.

Обязательно добавьте App::uses('Sanitize', 'Utility'); в свой файл модели перед классом.

В контроллере медиа вы можете использовать:

$result = $this->Media->search($query); 

который возвращает что-то вроде, если запрос «ок»:

array(
    0 => array(
     'id' => '12', 
     'name' => 'Carly', 
     'type' => 'book' 
    ), 
    1 => array(
     'id' => '19', 
     'name' => 'Camden', 
     'type' => 'book' 
    ), 
    2 => array(
     'id' => '20', 
     'name' => 'Carter', 
     'type' => 'movie' 
    ) 
); 
+0

Если бы у меня была модель Media, то я мог бы это сделать, и я уже думал об этом, но у них слишком мало общего, поэтому слияние их сделает супер огромную таблицу (они уже огромны отдельно). – Loolooii

+0

Этот метод поиска будет работать точно так же, если вы поместите его в книгу, фильмы или игровую модель. –