Должен ли я использовать больше найти в этом случае? - PullRequest
1 голос
/ 08 января 2012

у меня есть два контроллера

Sections_controller.php
Articles_controller.php

Section model hasmany Article...

я хочу получать статьи в виде блоков, как и все новостные сайты ... у каждого блока есть название раздела со ссылками на статьи в этом разделе ... поэтому я используюэтот код ...... Первый блок

 $block1=$this->Article->find('all',
         array(
          'limit' => 4, // just fetch 4 articles
          'order' => array('Article.created'=>'DESC'), 
          'conditions' => array('Section_id' => 87)
            )
          );
            // set the section for the view
            $this->set(compact('block1'));

Второй блок

 $block2=$this->Article->find('all',
         array(
         'limit' => 4, // just fetch 4 articles
          'order' => array('Article.created'=>'DESC'),
        'conditions' => array('Section_id' => 88)
            )
          );
            // set the section for the view
            $this->set(compact('block2'));

и т. д.

у кого-нибудь есть лучший метод в этой задаче без повторного поиска кода .. примечание .. Я не могу передать $ id в функцию, потому что статьи должны отображаться при запросе примера индекса сайта (www.newssite.com)

Ответы [ 2 ]

1 голос
/ 09 января 2012

Любая находка должна быть сделана в модели, а не в контроллере - это следует структуре MVC, а также мантре «толстые модели, тощие контроллеры», которая помогает придерживаться идеи MVC.

Это не только способ, которым это «должно» быть сделано, но также позволит вам иметь код только в одном месте:

//in the Article model
function getArticlesBySection($id) {
     $articles = $this->find('all', array(
         'limit' => 4,
         'order' => array('Article.created'=>'DESC'),
         'conditions' => array('Section_id' => $id)
     ));
    return $articles;
}

//in the Articles controller
$block1 = $this->Article->getArticlesBySection('87');
$block2 = $this->Article->getArticlesBySection('88');
$this->set(compact('block1', 'block2'));

Вышеприведенное должно прекрасно работать для того, что выхочу сделать , но вы всегда можете многое сделать, чтобы улучшить его - например, сделать его более гибким, приняв множество параметров:

//in the Article model
function getArticles($id, $opts = null) {
    $params = array();

    //limit
    $params['limit'] = 100; //catchall if no limit is passed
    if(!empty($opts['limit'])) $params['limit'] = $opts['limit'];

    //order
    $params['order'] = array('Article.created'=>'DESC');
    if(!empty($opts['order'])) $params['order'] = $opts['order'];

    //conditions
    $params['conditions'] = array();
    if(!empty($opts['sections'])) array_push($params['conditions'], array('Section_id'=>$opts['sections']));

    $articles = $this->find('all', $params);
    return $articles;
}

//in the Articles controller
$opts = array('limit'=>4, 'sections'=>array('87'));
$block1 = $this->Article->getArticles($opts);

$opts['sections'] = array('88');
$block2 = $this->Article->getArticles($opts);

ЯКонечно, есть вещи, которые можно сделать, чтобы сделать это более скудным ... и т. д., но это то, как мне нравится писать это для простоты использования и удобочитаемости, и, по крайней мере, дает вам представление о методах модели ивозможность использовать и повторно использовать их для различных целей.

0 голосов
/ 08 января 2012

Вы можете сделать это с помощью простого запроса MySQL, но я не уверен, как вы поместите его в функцию "торт" model->find. Вы можете сделать что-то вроде этого:

$articles = $this->Article->query("SELECT * FROM articles a WHERE (SELECT COUNT(*) FROM articles b WHERE a.Section_id = b.Section_id AND a.created < b.created) < 4 ORDER BY a.Section_id, a.created DESC");

/* if you look at the results, you should have the 4 latest articles per section. 
Now you can loop through and set up an array to filter them by section. Modify to fit your needs */

foreach($articles as $article) {
    $results[$article['Article']['Section_id']][] = $article;
}

$this->set('results',$results);
...