cakephp 3保存自引用belongsToMany

时间:2017-01-28 23:17:00

标签: php cakephp cakephp-3.x

我有一个nodes表和一个nodes_nodes表。

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'

}

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

1 个答案:

答案 0 :(得分:0)

您没有正确遵循命名约定。 belongsToMany关联的属性名称默认为小写,强调了关联别名的多个变体,即parent_nodeschild_nodes。如果需要,可以通过propertyName关联选项更改此选项。

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

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

另见