1
votes

I have a model association that works as followed:

Users hasAndBelongsToMany Tags

I want to be able to paginate a group of users based on their tags. Users can have many tags and filter requested can be complex i.e. a query can ask for all the users with tags A and B but not C. Its way more manageable to handle this by using pagination on tags (so that the condiditions array can apply to the Tag model) and getting back the users that are within that tags subset.

The issue then comes when trying to paginate, because I set up the pagination as followed:

$this->paginate = array(
    'conditions' => $conditions, 
    'contain' => array('User'), 
    'limit' => 5, 
);

$this->paginate('Tag')

So then pagination does exactly what is expected, it returns the array for pagination based on tags, but what I want is to paginate by the users. Switching the pagination to hinge on the users creates its own set of problems ('that is what I was using before'). Just pagination exist for model relates like this? I feel like this is the type of thing cakephp might be able to do. Thank you to anyone who helps.

2
could you switch it the other way and put a conditions in so select User by it's Tag?scrowler
@scrowler Nope, I tried that, it creates its own set of problems. This is a workaround, I think what has to happen is I need to override the pagination method, but I not sure how to do that yet.usumoio

2 Answers

1
votes

Place this into the model.

function paginateCount($conditions = null, $recursive = 0, $extra = array()) {
        $parameters = compact('conditions');
        $this->recursive = $recursive;
        $count = $this->find('count', array_merge($parameters, $extra));
        if (isset($extra['group'])) {
            $count = $this->getAffectedRows();
        }
        return $count;
    }
1
votes

You should use custom finder: cakephp documentation link. In you example in Users Model create protected function:

protected function _findUsersByTag($state, $query, $results = array()) {
    if($state == 'before') {
       $query['joins'] = array(
          'Tag' => array('type' => 'inner', 'alias' => 'Tag', 'table' => 'tags', 'conditions' => array('Users.tag_id = Tag.id')
       );
     return $query; 
    }

    return $results;
}

Second add in Users Model:

public $findMethods = array('usersByTag' =>  true);

And in the controller you definie you pagination to use custom finder using 0 index of array or in 2.3 and higther cake version property called findType:

public $pagination = array('User' => array(
   'usersByTag',
   'limit' => 5, 
   'conditions' => $conditions
));