2
votes

Alright, I have some issues understanding how the associations are working, particularly belongsTo here is my setup:

Articles can have multiple Categories
Categories can belong to multiple Articles

so in my database i have 3 tables: articles, categories and a join table articles_categories

Table/ArticlesTable.php:

public function initialize(array $config)
{
    $this->addBehavior('Timestamp');
    $this->table('articles');
    $this->belongsTo('Users');
    $this->belongsToMany('Categories', [
        'through' => 'ArticlesCategories',
        'alias' => 'Categories',
        'foreignKey' => 'article_id',
        'joinTable' => 'articles_categories',
        'targetForeignKey' => 'category_id'

    ]);

}

Table/CategoriesTable.php:

public function initialize(array $config)
{
    $this->table('categories');
    $this->displayField('name');
    $this->primaryKey('id');
    $this->addBehavior('Timestamp');
    $this->belongsToMany('Articles', [
        'through' => 'ArticlesCategories',
        'alias' => 'Articles',
        'foreignKey' => 'category_id',
        'joinTable' => 'articles_categories',
        'targetForeignKey' => 'article_id'
    ]);
}

Table/ArticlesCategoriesTable.php:

public function initialize(array $config)
{
    $this->belongsTo('Articles');
    $this->belongsTo('Categories');
}

Now inside in the view action CategoriesController.php i can overview a particular category and i need to retrieve some articles related to that category. What is the right way to do such a thing? Here is what i have:

public function view($id = null)
{
    $category = $this->Categories->find('all',['limit'=>1])->where(['Categories.id' => $id])->contain(['Articles']);
    $this->set(['category'=> $category]);
}

It kinda does the job but I'd also need to be able to limit the number of related articles..

1
"Categories can belong to multiple Articles" why? - Guillermo Mansilla
you can have multiple Articles with the same Category - user3813360

1 Answers

3
votes

you can modify the query object used to load the associated models:

$category = $this->Categories->find('all',['limit'=>1])
    ->where(['Categories.id' => $id])
    ->contain(['Articles' => function($q) {
        $q->limit(10);  
        return $q;
    }    
]);

edit: or you can do

$category = $this->Categories->get($id, 
[
    'contain' => [
        'Articles' => function($q) {
            $q->limit(10);  
            return $q;
    }    
]);

or maybe if you want the Articles without the Category data you can use matching

$articles = $this->Categories->Articles->find()
    ->matching('Categories', function ($q) use $id{
        return $q->where(['id' => $id])
    ->limit(10);

I did not tested the last one but I think something like that should work

But as you can see the complexity is more o less the same