BelongsToMany正确检索和删除,而不在CakePHP 3.x中更新/保存

问题描述

CakePHP 3.8.13-我有一个表模型,该模型可以从表中检索相关数据并将其删除,但是在更新/添加条目时,由于某种原因它不会更改此数据。因此,这似乎是一个正确的设置,但是并没有更新/添加它们。简而言之,它是一个“问题”表和一个“分区”表,以及一个名为“ questions_divisions”的关系表。在此关系表中,有一个question_id和division_id列。如果我在那里手动添加删除条目,一切似乎都可以。仅当执行patchEntity和保存时,它不会这样做。这是发布数据:

  'name' => string 'Some name' (length=8)
  'questiontype_id' => string '1' (length=1)
  'extra' => string '' (length=0)
  'answer' => string '' (length=0)
  'datafield' => string 'Person.firstname' (length=16)
  'divisions' => 
    array (size=1)
      '_ids' => 
        array (size=3)
          0 => string '1' (length=1)
          1 => string '7' (length=1)
          2 => string '5' (length=1)

这是执行的代码(因此上面的发布数据是$ this-> request-> getData()):

$question = $this->Questions->patchEntity($question,$this->request->getData());
            if ($this->Questions->save($question)) {

对于不同的模型,所有这些或多或少都与应用程序中其他地方发生的相同,实际上是在添加/更新除法。我还清除了/ tmp / cache,以防万一,似乎没有达到目的。我在这里茫然。

这是整个表格模型:

<?PHP

namespace App\Model\Table;

use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;

/**
 * Questions Model
 *
 * @property \App\Model\Table\Questiontypestable|\Cake\ORM\Association\BelongsTo $Questiontypes
 * @property \App\Model\Table\ActivitiesTable|\Cake\ORM\Association\BelongsToMany $Activities
 * @property \App\Model\Table\BookingformsTable|\Cake\ORM\Association\BelongsToMany $Bookingforms
 * @property \App\Model\Table\DivisionsTable|\Cake\ORM\Association\BelongsToMany $Divisions
 *
 * @method \App\Model\Entity\Question get($primaryKey,$options = [])
 * @method \App\Model\Entity\Question newEntity($data = null,array $options = [])
 * @method \App\Model\Entity\Question[] newEntities(array $data,array $options = [])
 * @method \App\Model\Entity\Question|bool save(\Cake\Datasource\EntityInterface $entity,$options = [])
 * @method \App\Model\Entity\Question|bool saveOrFail(\Cake\Datasource\EntityInterface $entity,$options = [])
 * @method \App\Model\Entity\Question patchEntity(\Cake\Datasource\EntityInterface $entity,array $data,array $options = [])
 * @method \App\Model\Entity\Question[] patchEntities($entities,array $options = [])
 * @method \App\Model\Entity\Question findOrCreate($search,callable $callback = null,$options = [])
 */
class QuestionsTable extends Table {

    public function beforeFind ($event,$query,$options,$primary) {
        $order = $query->clause('order');
        if ($order === null || !count($order)) {
            $query->order([$this->getAlias() . '.name' => 'ASC']);
        }
    }

    /**
     * Initialize method
     *
     * @param array $config The configuration for the Table.
     * @return void
     */
    public function initialize(array $config) {
        parent::initialize($config);

        $this->setTable('questions');
        $this->setdisplayField('name');
        $this->setPrimaryKey('id');

        $this->addBehavior('Search.Search');
        $this->addBehavior('Page');

        $this->hasMany('Questions_divisions',[
            'foreignKey' => 'question_id'
        ]);

        $this->belongsTo('Questiontypes',[
            'foreignKey' => 'questiontype_id','joinType' => 'INNER'
        ]);
        $this->belongsToMany('Activities',[
            'foreignKey' => 'question_id','targetForeignKey' => 'activity_id','joinTable' => 'activities_questions'
        ]);
        $this->belongsToMany('Bookingforms',[
            'foreignKey' => 'questions_id','targetForeignKey' => 'bookingforms_id','joinTable' => 'questions_bookingforms'
        ]);
        $this->belongsToMany('Divisions','targetForeignKey' => 'division_id','joinTable' => 'questions_divisions'
        ]);

        //Setup searchfield
        $this->behaviors()->Page->searchSetup($this->behaviors()->Search->searchManager(),$this->searchForm());
    }

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

        $validator
                ->scalar('name')
                ->maxLength('name',500)
                ->requirePresence('name','create')
                ->notEmpty('name');

        $validator
                ->scalar('extra')
                ->maxLength('extra',500)
                ->allowEmpty('extra');

        $validator
                ->scalar('answer')
                ->maxLength('answer',1500)
                ->allowEmpty('answer');

        $validator
                ->scalar('datafield')
                ->maxLength('datafield',500)
                ->requirePresence('datafield','create')
                ->notEmpty('datafield');

        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(['questiontype_id'],'Questiontypes'));

        return $rules;
    }

    /**
     * Returns an array which describes the search form
     *
     * @return Array with search setup
     */
    public function searchForm() {
        //Set up search form
        $search_data = [['id' => 'name','label' => 'Naam','type' => 'textfield','fields' => ['name']],['id' => 'Questiontypes_id','label' => 'Vraagtype','type' => 'multiselect','fields' => ['Questiontypes.id'],'options' => $this->Questiontypes->find('list')],['id' => 'datafield','label' => 'Dataveld','fields' => ['datafield']]
        ];
        return $search_data;
    }

}

解决方法

似乎就像在$ _accessible数组中(在Model / Entity内部)添加此列可以解决问题……这就是为什么它可以检索数据但不编辑它的原因-也许是“可访问的”?不确定这是否是正确的名称,但是。.

protected $_accessible = [
   'name' => true,'extra' => true,'answer' => true,'datafield' => true,'questiontype_id' => true,'questiontype' => true,'activities' => true,'bookingforms' => true,'divisions' => true // this did the trick!
];