首页 > 解决方案 > 如何使用 Cakephp3 以一种好的方式配置树?

问题描述

我正在做一个需要树来构造类别的项目。问题是我找不到如何在我的模型之间加入表格,或者它可能与控制器本身有关。当我填写表格并发布它时,只写了表格类别,Categorylangs 中没有任何反应。我很确定这是一个小错误或者我在这里误解了一些简单的事情..谢谢

    public function add()
    {
        $category = $this->Categories->newEntity();
        $category->categorylangs = $this->Categories->Categorylangs->newEntity();

        if ($this->request->is(['patch', 'post', 'put'])) {

            $category = $this->Categories->patchEntity($category, $this->request->getData());

            debug($category);
            die();

            if ($this->Categories->save($category)) {
                $this->Flash->success(__('The category has been saved.'));

                return $this->redirect(['action' => 'index']);
            }
            $this->Flash->error(__('The category could not be saved. Please, try again.'));
        }
        $this->set(compact('category'));

    }



class CategoriesTable extends Table


        $this->setTable('categories');
        $this->setDisplayField('id');
        $this->setPrimaryKey('id');

        $this->addBehavior('Tree');

        $this->hasMany('ChildCategories', [
            'className' => 'Categories',
            'foreignKey' => 'parent_id'
        ]);
        $this->hasMany('Categorylangs', [
            'foreignKey' => 'category_id'
        ]);
        // $this->hasMany('Privatequestions', [
        //     'foreignKey' => 'category_id'
        // ]);
        // $this->hasMany('Publicquestions', [
        //     'foreignKey' => 'category_id'
        // ]);
        // $this->hasMany('Userpros', [
        //     'foreignKey' => 'category_id'
        // ]);
    }

    /**
     * Default validation rules.
     *
     * @param \Cake\Validation\Validator $validator Validator instance.
     * @return \Cake\Validation\Validator
     */
    public function validationDefault(Validator $validator)
    {
        $validator
            ->nonNegativeInteger('id')
            ->allowEmptyString('id', 'create');

        $validator
            ->boolean('active')
            ->requirePresence('active', 'create')
            ->allowEmptyString('active', false);

        return $validator;
    }

    /**
     * Returns a rules checker object that will be used for validating
     * application integrity.
     *
     * @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
     * @return \Cake\ORM\RulesChecker
     */
    public function buildRules(RulesChecker $rules)
    {
        return $rules;
    }
}


class CategorylangsTable extends Table
{

    {
        parent::initialize($config);

        $this->setTable('categorylangs');
        $this->setDisplayField('id');
        $this->setPrimaryKey('id');

        $this->belongsTo('Categories', [
            'foreignKey' => 'category_id',
            'joinType' => 'INNER'
        ]);
        $this->belongsTo('Languages', [
            'foreignKey' => 'language_id',
            'joinType' => 'INNER'
        ]);
    }

    /**
     * Default validation rules.
     *
     * @param \Cake\Validation\Validator $validator Validator instance.
     * @return \Cake\Validation\Validator
     */
    public function validationDefault(Validator $validator)
    {
        $validator
            ->nonNegativeInteger('id')
            ->allowEmptyString('id', 'create');

        $validator
            ->scalar('label')
            ->maxLength('label', 350)
            ->requirePresence('label', 'create')
            ->allowEmptyString('label', false);

        $validator
            ->scalar('slug')
            ->maxLength('slug', 450)
            ->requirePresence('slug', 'create')
            ->allowEmptyString('slug', false);

        $validator
            ->scalar('description')
            ->requirePresence('description', 'create')
            ->allowEmptyString('description', false);

        return $validator;
    }

    /**
     * Returns a rules checker object that will be used for validating
     * application integrity.
     *
     * @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
     * @return \Cake\ORM\RulesChecker
     */
    public function buildRules(RulesChecker $rules)
    {
        $rules->add($rules->existsIn(['category_id'], 'Categories'));
        $rules->add($rules->existsIn(['language_id'], 'Languages'));

        return $rules;
    }
}


The view with the form to fill the 2 tables:

<nav class="large-3 medium-4 columns" id="actions-sidebar">
    <ul class="side-nav">
        <li class="heading"><?= __('Actions') ?></li>
        <li><?= $this->Html->link(__('List Categories'), ['action' => 'index']) ?></li>
    </ul>
</nav>
<div class="categories form large-9 medium-8 columns content">
    <?= $this->Form->create($category) ?>
    <fieldset>
        <legend><?= __('Add Category') ?></legend>
        <?php
            echo $this->Form->control('parent_id', ['options' => $parentCategories, 'empty' => __('root')]);
            echo $this->Form->control('categorylangs.label');
            echo $this->Form->control('categorylangs.description');
            echo $this->Form->control('categorylangs.language_id');
            echo $this->Form->control('active');
        ?>
    </fieldset>
    <?= $this->Form->button(__('Submit')) ?>
    <?= $this->Form->end() ?>
</div>

这是来自 Categoriescontroller.php 的调试,显示数据未按应有的方式传输,但我不知道如何修复它...

/src/Controller/Admin/CategoriesController.php(第 60 行)对象(App\Model\Entity\Category){

'categorylangs' => [],
'active' => false,
'[new]' => true,
'[accessible]' => [
    'parent_id' => true,
    'lft' => true,
    'rght' => true,
    'active' => true,
    'parent_category' => true,
    'child_categories' => true,
    'categorylangs' => true,
    'privatequestions' => true,
    'publicquestions' => true,
    'userpros' => true
],
'[dirty]' => [
    'categorylangs' => true,
    'active' => true
],
'[original]' => [
    'categorylangs' => object(App\Model\Entity\Categorylang) {

        '[new]' => true,
        '[accessible]' => [
            'label' => true,
            'slug' => true,
            'description' => true,
            'category_id' => true,
            'language_id' => true,
            'category' => true,
            'language' => true
        ],
        '[dirty]' => [],
        '[original]' => [],
        '[virtual]' => [],
        '[hasErrors]' => false,
        '[errors]' => [],
        '[invalid]' => [],
        '[repository]' => 'Categorylangs'

    }
],
'[virtual]' => [],
'[hasErrors]' => false,
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Categories'

}

标签: databasemodeltreecakephp-3.0

解决方案


Categorylangs是一个hasMany关系,不是hasOne,所以你的字段名应该是categorylangs.0.label,不是categorylangs.label。您需要它生成一个实体数组,即使该数组中只有一个实体。

并且$category->categorylangs = $this->Categories->Categorylangs->newEntity();在这里没有意义, 的值categorylangs将被patchEntity调用覆盖。


推荐阅读