CakePHP: Pagination with query constraints on related hasMany field?
Similar to this question — but due to my ineptitude with CakePHP, I can't seem to figure this out. Here is my setup.
I've got a model name User
which has many Comments
. I want a list of all invisible Users
with at least one Comment
. Our controller has methods set up to set records
as $this->paginate()
without any values passed to it; instead, the $paginate
var is set up with conditions and things like that.
class UsersController extends AppController {
var $name = 'Users';
var $paginate;
function new_users() {
$this->User->recursive = 1;
$this->paginate['User']['contain'][] = 'Comment';
$this->paginate['User']['order'] = 'User.DateCreated DESC';
$conditions = array();
// Get invisible开发者_如何学Go users...
$conditions[] = array('User.Status = ?' => 'Invisible');
$conditions[] = array('User.Enabled' => true);
// ...with at least one active comment
$conditions[] = array('Comment.Status' => 'Active');
// Load these conditions and fire pagination to render the view
$this->paginate['User']['conditions'] = $conditions;
$this->set('records', $this->paginate());
}
}
I am so new to CakePHP that a lot of this stuff is still over my head. I just want a list of Users
that have active Comments
. Right now, this query nets me 0 users. If I take out the line regarding Comment.Status
, the query goes through, but I get all invisible Users
regardless of if they have comments.
Everywhere online that I've seen the paginate()
call, things have been passed to it (like paginate('User', array('Comment.Status' => 'Active'))
, which I've tried and nets me nothing).
Edit: I've got the following code, while cleaner, still gives me the same results.
$this->paginate = array(
'conditions' => array(
'User.Status' => 'Invisible',
'User.Enabled' => true,
),
'contain' => array(
'Comment' => array(
'conditions' => array(
'Comment.Status' => 'Active',
)
)
),
'recursive' => 1,
'order' => 'User.DateCreated DESC',
);
$data = $this->paginate('User');
I usually use the paginate changes on-the-fly hehe. Here is some example code.
$this->paginate = array(
'conditions' => array('Recipe.title LIKE' => 'a%'),
'limit' => 10 );
$data = $this->paginate('Recipe');
Here you can read more about controller setup for paginations. But if you already have the associations in the model (hasMany, etc) the data is auto-fetched if you put recursive to 1 without the need of contain (you may still use it to get only the data you want). an example of how it will look for you:
$this->paginate = array(
'conditions' => array(
'User.Status' => 'Invisible',
'User.Enabled' => true
),
'contain' => array('Comment' => array(
'conditions' => array('Comment.Status' => 'Active')
)),
'recursive' => 1,
'order' => 'User.DateCreated DESC'
);
$data = $this->paginate('User');
This is what you put in your post. If you paste the sql query of what you want, I may be able to help you more. Also, try checking the sql output so you know if something is wrong in the conditions. if you don't have and don't know how to put the sql output just do this.
var_dump($this->User->getQuery(
'conditions' => array(
'User.Status' => 'Invisible',
'User.Enabled' => true,
'Comment.Status' => 'Active'
),
'contain' => 'Comment',
'order' => 'User.DateCreated DESC'
));
Hope it helps you, if not, leave me a comment.
EDIT: This is what you need to do to get what you want. :D Change the table and the condition to fit your needs.
$this->paginate = array(
'conditions' => array(
'User.Status' => 'Invisible',
'User.Enabled' => true
),
'joins' => array(
array(
'table' => 'name_of_comment_table',
'alias' => 'Comment',
'type' => 'inner',
'conditions' => array(
'Comment.user_id = User.id',
'Comment.Status' => 'Active'
)
)
),
'contains' => array('Comment'),
'group' => 'User.id',
'recursive' => 1,
'order' => 'User.DateCreated DESC'
);
$data = $this->paginate('User');
精彩评论