I'm making a blog and I want to be able to assign multiple categories or tags for an article and an article can have multiple categories.
This is what I have in my database: articles, categories and the join table articles_categories.
PROJECT:

JOIN TABLE:

in my Table/ArticlesTable.php:
public function initialize(array $config)
{
$this->addBehavior('Timestamp');
$this->belongsToMany('Categories', [
'alias' => 'Categories',
'foreignKey' => 'article_id',
'targetForeignKey' => 'category_id',
'joinTable' => 'articles_categories'
]);
}
in my Table/CategoriesTable.php:
public function initialize(array $config)
{
$this->table('categories');
$this->displayField('name');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->belongsToMany('Articles', [
'alias' => 'Articles',
'foreignKey' => 'category_id',
'targetForeignKey' => 'article_id',
'joinTable' => 'articles_categories'
]);
}
When a user adds an article, it needs to add the article and then the ids in the join table here's my ArticlesController/add method:
public function add()
{
$article = $this->Articles->newEntity();
if ($this->request->is('post'))
{
$article = $this->Articles->patchEntity($article, $this->request->data);
$article->user_id = $this->Auth->user('id');
if ($result = $this->Articles->save($article))
{
$this->Flash->success(__('Your article has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('Unable to add your article.'));
}
$this->set(['article'=>$article,'buttontext'=>'Add Article']);
$categories = $this->Articles->Categories->find('list');
$this->set(compact('categories'));
}
add.ctp view:
echo $this->Form->create($article, ['class' => 'form-group']); echo $this->Form->input('articlecategory',['options' => $categories,'id'=>'magicselect','multiple'=>true,'class'=>'form-control']); echo $this->Form->input('title', ['class'=>'form-control', 'maxlength'=>'50']); echo $this->Form->input('body', ['rows' => '8', 'class'=>'form-control', 'style'=>'margin-bottom:10px;resize: none', 'maxlength'=>'5000']); echo $this->Form->button(__($buttontext), ['class'=>'btn btn-success']); echo $this->Form->end();
and what I get after submitting the form debug($this->request->data):
[
'articles_categories' => [
(int) 0 => '1'
],
'title' => 'test article',
'body' => 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.'
]
My problem is that I'm not sure if my associations are correct. How do I automatically insert the data in the join table?
That is not the correct format for a belongsToMany association, see
The property name should by default be the underscored, plural name of the association, so in this case categories.
_ids keySince you want to link your article to already existing categories, you should additionally use the magic _ids key to pass the IDs of the selected categories, the marshaller will then take care of the rest, that is pick and insert the appropriate Category entities based on the given IDs, see
http://book.cakephp.org/3.0/en/orm/saving-data.html#converting-belongstomany-data
All you need to do is to append it to the field/propertyname, like categories._ids, ie your form input should be defined like this:
$this->Form->input('categories._ids', [
'options' => $categories,
'id' => 'magicselect',
'multiple' => true,
'class' => 'form-control'
]);
Note that it's not necessary to explicitly pass the options, if you follow the conventions, ie use the underscored plural of the association name, then the form helper will be able to automagically pick up the variable just like it does for other input fields.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With