cakephp 3 保存自引用 belongsToMany

cakephp 3 saving self referencing belongsToMany

我有一个nodestable和一个nodes_nodestable。

nodes table +----+--------+ | id | name | +----+--------+ | 1 | Node1 | | 2 | Node2 | | 3 | Node3 | | 4 | Node4 | | 5 | Node5 | +----+--------+

nodes_nodes table +----+----------------+---------------+ | id | parent_node_id | child_node_id | +----+----------------+---------------+ | 1 | 2 | 3 | | 2 | 1 | 4 | | 3 | 1 | 5 | +----+----------------+---------------+

一个节点可以有一个或多个父节点和一个或多个子节点

NodesTable.php:

public function initialize(array $config)
{
    parent::initialize($config);

    $this->table('nodes');
    $this->displayField('name');
    $this->primaryKey('id');

    $this->addBehavior('Timestamp');

    $this->belongsToMany('ChildNodes', [
        'className' => 'Nodes',
        'joinTable' => 'nodes_nodes',
        'foreignKey' => 'parent_node_id',
        'targetForeignKey' => 'child_node_id'
    ]);

    $this->belongsToMany('ParentNodes', [
        'className' => 'Nodes',
        'joinTable' => 'nodes_nodes',
        'foreignKey' => 'child_node_id',
        'targetForeignKey' => 'parent_node_id'
    ]);

}

Node.php

class Node extends Entity
{

    protected $_accessible = [
        '*' => true,
        'id' => false,
        'ParentNodes' => true,
        'ChildNodes' => true,
        '_joinData' => true,
    ];
}

NodesController.php

public function add()
{
    $node = $this->Nodes->newEntity();
    if ($this->request->is('post')) {
        $node = $this->Nodes->patchEntity($node, $this->request->data);
        debug($node);
        if ($this->Nodes->save($node)) {
            $this->Flash->success(__('The node has been saved.'));

            return $this->redirect(['action' => 'index']);
        }
        $this->Flash->error(__('The node could not be saved. Please, try again.'));
    }
    $nodes = $this->Nodes->find('list', ['limit' => 200]);
    $this->set(compact('node', 'nodes'));
    $this->set('_serialize', ['node']);
}

add.ctp形式:

<?= $this->Form->create($node) ?>
<fieldset>
    <legend><?= __('Add Node') ?></legend>
    <?php
        echo $this->Form->input('name');
        echo $this->Form->input('ParentNodes._ids', ['options' => $nodes]);
        echo $this->Form->input('ChildNodes._ids', ['options' => $nodes]);
    ?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>

add() 函数中 $node 实体调试的输出:

object(App\Model\Entity\Node) {

    'name' => 'Node6',
    'ParentNodes' => [
        '_ids' => [
            (int) 0 => '15',
            (int) 1 => '12'
        ]
    ],
    'ChildNodes' => [
        '_ids' => [
            (int) 0 => '13'
        ]
    ],
    '[new]' => true,
    '[accessible]' => [
        '*' => true,
        'ParentNodes' => true,
        'ChildNodes' => true,
        '_joinData' => true
    ],
    '[dirty]' => [
        'name' => true,
        'ParentNodes' => true,
        'ChildNodes' => true
    ],
    '[original]' => [],
    '[virtual]' => [],
    '[errors]' => [],
    '[invalid]' => [],
    '[repository]' => 'Nodes'

}

当我保存一个新节点时,关联并没有被保存。 我尝试在 $this->Nodes->save() 上添加 ['associated' => ['ParentNodes', 'ChildNodes']] 但没有成功

您没有正确遵循命名约定。 属性 belongsToMany 关联的名称默认为小写、带下划线的关联别名的复数变体,即 parent_nodeschild_nodes。如果需要,可以通过 propertyName 关联选项更改。

echo $this->Form->input('parent_nodes._ids', ['options' => $nodes]);
echo $this->Form->input('child_nodes._ids', ['options' => $nodes]);

此外,如果您已将 * 设置为 true,则无需将属性添加到 $_accessible,因为这样可以批量分配所有内容。

另见