My Category Model:
class Category extends AppModel {
public $displayField = 'name';
// public $actsAs = array('Containable');
public $hasAndBelongsToMany = array(
'Post' => array(
'className' => 'Post',
'joinTable' => 'categories_postss',
'foreignKey' => 'category_id',
'associationForeignKey' => 'post_id',
'unique' => 'keepExisting'
)
);
}
$params['contain'] = array('Post' => array(
'limit'=> 3));
pr($this->Category->find('first',$params)); exit;
It is fetching all Posts, irrespective of limit.
What I want to do:
I have this page where I ma listing all the categories and latest 5 posts related to it.
I want to limit the associated model to only 5 rows.
Any ideas?
Containable behavior is not in use
The most likely reason for this problem is that the containable behavior is not being used at all.
Compare, for the below code example:
$results = $this->Category->find('first', array(
'contain' => array(
'Post' => array(
'limit' => 3
)
)
));
Without containable behavior, it'll generate the following queries:
SELECT ... FROM `crud`.`categories` AS `Category` WHERE 1 = 1 LIMIT
SELECT ... FROM `crud`.`posts` AS `Post`
JOIN `crud`.`categories_posts` AS `CategoriesPost` ON (...)
With containable behavior, it'll generate the following queries:
SELECT ... FROM `crud`.`categories` AS `Category` WHERE 1 = 1 LIMIT
SELECT ... FROM `crud`.`posts` AS `Post`
JOIN `crud`.`categories_posts` AS `CategoriesPost` ON (...) LIMIT 3
Given this (and the code in the question) check that the AppModel has the containable behavior in $actsAs
:
<?php
// app/Model/AppModel.php
class AppModel extends Model {
public $actsAs = array('Containable');
}
Limit always required?
Alternatively, or possibly in addition, you may prefer to put a limit in the association definition - To do so just define the 'limit' key:
class Category extends AppModel {
public $hasAndBelongsToMany = array(
'Post' => array(
'limit' => 100, // default to a high but usable number of results
)
);
}
the hasAndBelongsToMany
relationship seems unnecessary to me. I think you only need Category hasMany Post
and Post belongsTo Category
relationships. Add category_id
to the posts
table. Make both models actAs containable
.
Post Model
class Post extends AppModel {
public $actsAs = array('Containable');
var $belongsTo = array(
'Category' => array(
'className' => 'Category',
'foreignKey' => 'category_id'
),
// ... more relationships
);
Category Model
class Category extends AppModel {
public $actsAs = array('Containable');
var $hasMany = array(
'Post' => array(
'className' => 'Post',
'foreignKey' => 'category_id'
),
// ... more relationships
);
Categories Controller
class CategoriesController extends AppController {
public $paginate = array(
'Category' => array(
'contain' => array(
'Post' => array(
'limit' => 3
), // end Post
) // end Category contain
) // end Category pagination
); // end pagination
public function index() {
// for paginated results
$this->set('categories', $this->paginate());
// for find results
$this->Category->contain(array(
'Post' => array(
'limit' => 3
)
));
$this->set('categories', $this->Category->find('all'));
}