PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Tuesday, January 11, 2022

[FIXED] Insert/Delete methods for self-referencing belongsToMany association

 January 11, 2022     cakephp, cakephp-3.0     No comments   

Issue

I’m struggling with a self-referencing belongsToMany association. To be clear I have a Models table and each model can have multiple accessories, which are also models. So I have a linking table, Accessories, with a model_id (the “parent” model) and an accessory_id (the “child” model).

I finally found how to declare this in the ModelsTable :

$this->belongsToMany('AccessoryModels', [
    'className' => 'Models',
    'through' => 'Accessories',
    'foreignKey' => 'model_id',
    'targetForeignKey' => 'accessory_id'
]);
$this->belongsToMany('ParentAccessoryModels', [
    'className' => 'Models',
    'through' => 'Accessories',
    'foreignKey' => 'accessory_id',
    'targetForeignKey' => 'model_id'
]);

I also got it working to retrieve these data in the Models view.

But I now have some issues for the addAccessory (and deleteAccessory) method in the Models controller and views.

Here is it in the controller :

public function addAccessory($id = null)
{
    $model = $this->Models->get($id, [
        'contain' => []
    ]);
    if ($this->getRequest()->is(['patch', 'post', 'put'])) {
        $accessory = $this->getRequest()->getData();
        if ($this->Models->link($model, [$accessory])) {
            return $this->redirect(['action' => 'view', $model->id]);
        }
    }
    $models = $this->Models
        ->find('list', ['groupField' => 'brand', 'valueField' => 'reference'])
        ->order(['brand' => 'ASC', 'reference' => 'ASC']);
    $this->set(compact('model', 'models'));
}

The view is only a select dropdown with the list of all available models (I'm using a plugin, AlaxosForm, but it takes the original CakePHP control() function behaviour) :

echo $this->AlaxosForm->label('accessory_id', __('Accessory'), ['class' => 'col-sm-2 control-label']);
echo $this->AlaxosForm->control('accessory_id', ['options' => $models, 'empty' => true, 'label' => false, 'class' => 'form-control']);
echo $this->AlaxosForm->button(___('Submit'), ['class' => 'btn btn-default']);

The problem is that the addAccessory() function won't work when getting the submitted data from the form. I see the problem, as when posting the inserted values, only an array with one accessory_id is given (for example ['accessory_id' => 1] and the link() doesn't know what to do with it. So I think it’s an issue about data formatting but don’t see how to get it correctly.


Solution

Saving links (like any other ORM saving methods) requires to pass entities, anything else will either be ignored, or trigger errors.

So you have to use the accessory_id to obtain an entity first, something like:

$accessoryId = $this->getRequest()->getData('accessory_id');
$accessory = $this->Models->AccessoryModels->get($accessoryId);

Furthermore you need to use the model/table that corresponds to the target entities (second argument) that you want to link (to the first argument), ie you'd have to use AccessoryModels, like:

$this->Models->AccessoryModels->link($model, [$accessory])

See also

  • Coobook > Database Access & ORM > Saving Data > Associate Many To Many Records


Answered By - ndm
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing