cakephp-2.3

Requested address not found error in cakephp pagination


I am trying to create pagination with cakephp but it's giving me error address not found. The requested address '/mygroup/newsfeed/page:2' was not found on this server.

I getting the following error in my log file

Error: [MissingActionException] Action GroupsController::page:2() 
could not be found.
Exception Attributes: array (
'controller' => 'GroupsController',
'action' => 'page:2',
)

Please find my code below:

View:

<?php if($this->params['paging']['NewsFeed']['pageCount'] > 1): ?>
<?php $this->paginator->options(array('url' => array('controller' => 'groups', 
'action'  => 'newsfeed', 'sluggroup' => $groupdata['Group']['group_slug'])));?>
<div class="paginationbiz">
     <ul>
        <li class="prevnext disablelink"><?php echo $this->paginator->prev('« Prev',array()); ?></li>
        <li><?php echo $this->paginator->numbers(); ?></li>
        <li class="prevnext"><?php echo $this->paginator->next('Next »',array()); ?></li>
    </ul>
</div>
<?php endif; ?>

routes.php

 Router::connect('/:sluggroup/:action/*', array('controller' => 'groups', 
'action' =>   'newsfeed'),array('pass' => array('sluggroup')));

Controller:

 $this->paginate = array(
            'conditions' => array('NewsFeed.group_id'=>$groupdata['Group']['id'],'NewsFeed.status'=>'A'),
            'joins' => array(
                    array(
                            'alias' => 'newslikes',
                            'table' => 'news_feed_likes',
                            'type' => 'LEFT',
                            'conditions' => array('newslikes.news_feed_id = NewsFeed.id','newslikes.user_id'=>$this->Auth->user('id'),'newslikes.status'=>'1')
                    ),


            ),
            'fields' => array('IFNULL(newslikes.user_id,0) AS likestatus','NewsFeed.id','NewsFeed.group_id','NewsFeed.posted_message','NewsFeed.event_id','NewsFeed.event_desc','NewsFeed.event_slug','NewsFeed.event_title','NewsFeed.doc_id','NewsFeed.doc_title','NewsFeed.doc_file','NewsFeed.doc_path','NewsFeed.alert_id','NewsFeed.alert_title','NewsFeed.alert_desc','NewsFeed.created','NewsFeed.user_id','NewsFeed.status','NewsFeed.newslike'
                    ,'IFNULL(newslikes.status,0) AS status'),
            'order' => array(
                    'NewsFeed.updated' => 'desc'
            ),'limit' =>10, 'page'=>1,
    );

    $this->set('newsfeed', $this->paginate( $this->NewsFeed ) );

Solution

  • You have a similar question (without an answer too) because of the same problem.

    You're problem is that route

    Router::connect('/:sluggroup/:action/*', array('controller' => 'groups', 
                    'action' =>   'newsfeed'),array('pass' => array('sluggroup')));
    

    That, my friend, is killing you. For every url like this domain.url/your-controller/your-action, you're fine, because that url doesn't match your route. But, for urls like domain.url/your-controller/your-action/some-parameter, you get a match.

    domain.url/your-controller/your-action != /:sluggroup/:action/*   //ok case
    domain.url/sluggroup/action/*          == /:sluggroup/:action/*   //ok case
    
    //NOT THE MATCH THE MATCH YOU WANT
    domain.url/your-controller/your-action/params == /:sluggroup/:action/*   
    

    The only option I see is to change that route, otherwise this will keep happening to you, unwanted matches. Now, there's two options... well, probably more. If the urls that get the sluggroup parameters correspond to a single controller, let's call it "GroupsController", you can do something like

    Router::connect('/groups/:sluggroup/:action/*', array('controller' => 'groups', 
                    'action' =>   'newsfeed'),array('pass' => array('sluggroup')));
    

    and that will match urls like domain.com/groups/slug/action/etc, but, it will still give you problems with other actions for the same controller (like domain.com/groups/edit/2). You could avoid that adding more urls on top of that one for every action, like

    Router::connect('/groups/edit/*', array('controller' => 'groups', 
                    'action' =>   'edit')));
    Router::connect('/groups/edit', array('controller' => 'groups', 
                    'action' =>   'edit')));
    Router::connect('/groups/:sluggroup/:action/*', array('controller' => 'groups', 
                    'action' =>   'newsfeed'),array('pass' => array('sluggroup')));
    

    The other option is to make the route skip that rule with regex parameters

    Router::connect('/:sluggroup/:action/*', array('controller' => 'groups', 
                    'action' =>   'newsfeed'),
                     array('pass' => array('sluggroup'),
                     array('sluggroup' => '[^(groups)]')));
    

    I'm not good with regex, but the idea is that you only apply that route to urls where the sluggroup matches that regex, otherwise skip it and it will arrive to the correct route.

    Neither seem very mantainable, are you not okay with having your urls like domain.com/groups/newwsfeed/slug/other-params and keep it simple?