【发布时间】:2021-01-16 00:45:26
【问题描述】:
CakePHP 3.8.13 - 我有一个表模型,它可以从表中检索相关数据并将其删除,但是在更新/添加条目时,由于某种原因它不会更改此数据。所以这似乎是一个正确的设置,但它不会更新/添加它们。简而言之,它是一个“Questions”表和一个“Divisions”表,以及一个名为“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)
这是执行的代码(所以上面的post数据,就是$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 $data, 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', [
'foreignKey' => 'question_id',
'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', 'type' => 'textfield', 'fields' => ['datafield']]
];
return $search_data;
}
}
【问题讨论】:
-
在补丁前后调试
$question。另请解释保存时到底发生了什么,从您的解释中不清楚是只有部分数据没有被保存,还是根本没有保存。 -
@ndm 很抱歉这里没有完全清楚。一切都正确保存,没有额外添加的“部门”。这就是 belongsToMany('Divisions') 位。它确实检索它。保存后,分区(手动添加时)在路径/保存之前和之后都可用。只是不像我编辑它们的方式。因此,如果我像上面的帖子数据一样发送 3 个 id 作为分区,它仍然只能从数据库中获取 1 ......出于某种原因,它不会让我更新它,而只会检索(并且在执行 delete() 时,它也会从关系表中删除)。
-
修补前后
$question是什么样子的?特别是,divisions属性中有什么,该属性是否被标记为脏? -
感谢@GregSchmidt,您的调试让我进一步研究了这个模型,并发现accessible 也需要这个列名。这就是我实际上忘记添加的内容,现在它就像一个魅力。
标签: cakephp model cakephp-3.0 model-associations