Пару месяцев я был занят фреймворком cakePHP, и мне это очень нравится. В данный момент я работаю над очень новым проектом, и он выполняет свою работу так, как должен (я думаю ...), но я чувствую себя некомфортно из-за написанного мной кода. Фактически я должен оптимизировать свой запрос условий разбивки на страницы, чтобы я сразу получил правильные результаты (сейчас я манипулирую набором результатов с помощью набора вызовов метода Set :: extract.
Я нарисую соответствующие аспекты приложения. У меня есть модель Site, у которой есть отношение hasMany к модели SiteMeta. Эта последняя таблица выглядит следующим образом: id, site_id, ключ, значение, создано.
В этой последней модели я записываю несколько значений сайта в разные периоды. Имя ключа, который я хочу сохранить (например, alexarank, google pagerank, ...), и, конечно же, значение. Через определенный промежуток времени я позволяю моему приложению обновлять эту базу данных, чтобы я мог отслеживать эволюцию этих значений.
Теперь моя проблема заключается в следующем.
На странице обзора различных веб-сайтов (controller => Sites, action => index) я хотел бы показать страницу ТЕКУЩЕГО веб-сайта. Таким образом, мне нужна одна точная запись SiteMeta, где «созданное» поле является наибольшим, а значение в «ключе» должно соответствовать слову «pagerank». Я пробовал несколько вещей, которые я читал в сети, но ни одна из них не работала (сдерживаемые, bindmodel и т. Д.). Вероятно, я делаю что-то не так.
Прямо сейчас я получаю такие результаты, когда делаю $ this-> paginate
Array
(
[0] => Array
(
[Site] => Array
(
[id] => 1
[parent_id] => 0
[title] => test
[url] => http://www.test.com
[slug] => www_test_com
[keywords] => cpc,seo
[language_id] => 1
)
[SiteMeta] => Array
(
[0] => Array
(
[id] => 1
[site_id] => 1
[key] => pagerank
[value] => 5
[created] => 2010-08-03 00:00:00
)
[1] => Array
(
[id] => 2
[site_id] => 1
[key] => pagerank
[value] => 2
[created] => 2010-08-17 00:00:00
)
[2] => Array
(
[id] => 5
[site_id] => 1
[key] => alexa
[value] => 1900000
[created] => 2010-08-10 17:39:06
)
)
)
Чтобы получить PageRank, я просто перебираю все сайты и манипулирую полученным массивом. Далее я фильтрую результаты с помощью Set :: extract. Но это не совсем правильно :)
$sitesToCheck = $this->paginate($this->_searchConditions($this->params));
foreach($sitesToCheck as $site) {
$pagerank = $this->_getPageRank($site['Site']);
$alexa = $this->_getAlexa($site['Site']);
$site['Site']['pagerank'] = $pagerank;
$sites[] = $site;
}
if (isset($this->params['named']['gpr']) && $this->params['named']['gpr']) {
$rank = explode('-', $this->params['named']['gpr']);
$min = $rank[0];$max = $rank[1];
$sites = Set::extract('/Site[pagerank<=' . $max . '][pagerank>=' . $min .']', $sites);
}
$this->set(compact('sites', 'direction'));
Не могли бы вы, ребята, помочь мне подумать над решением этой проблемы? Заранее спасибо.
Спасибо за вклад. Я попробовал эти варианты (также что-то с bindmodel, но не работает), но все еще не могу заставить это работать так, как должно быть. Если я определю это
$this->paginate = array(
'joins'=> array(
array(
'table'=>'site_metas',
'alias'=>'SiteMeta',
'type' =>'inner',
'conditions' =>array('Site.id = SiteMeta.site_id')
)
),
);
Я получаю повторяющиеся результаты
У меня есть сайт с 3 разными записями SiteMeta и сайт с 2 разными записями.
Метод paginate возвращает мне 5 записей. Вероятно, есть простое решение для этого, но я не могу понять это:)
Также я попытался написать SQL-запрос сам, но, похоже, я не могу использовать магию пагинации в этом случае. Запрос, который я хотел бы имитировать с параметрами и условиями нумерации страниц, следующий. Запрос возвращается именно так, как я хотел бы получить.
$sites = $this->Site->query('SELECT * FROM sites Site, site_metas SiteMeta WHERE SiteMeta.id = (select SiteMeta.id from site_metas SiteMeta WHERE Site.id = SiteMeta.site_id AND SiteMeta.key = \'pagerank\' order by created desc limit 0,1 )');