我有这三个表:
在BookingsController中,我有两个功能:
当用户首次提交新的预订数据条目时,在为预订和会话创建并保存newEntity时,不会为文件创建和保存newEntity。但是,当正在更新和确认预订/会话时,即第一次创建文件中的newEntity时。由于Confirm函数可以多次使用,因此我使用条件if语句来确定是否存在关联的Files条目 - 如果存在,则创建newEntity for Files,修补然后保存。如果没有,它只是修补并保存。
在我的确认功能中:
public function confirm($id = null)
{
$booking = $this->Bookings->get($id,[
'contain' => ['Sessions']
]);
if ($this->request->is(['patch', 'post', 'put'])) {
$booking = $this->Bookings->patchEntity($booking, $this->request->data,[
'contain' => ['Sessions']
]);
$fileTable = TableRegistry::get('Files');
$findFiles = $fileTable->find()->where([
'session_id' => $session['id']
])->first();
if($findFiles == null){
$findFiles = $fileTable->newEntity();
$findFiles = $fileTable->patchEntity($findFiles, $data);
$findFiles->session_id = $booking['session']['id'];
if($fileTable->save($findFiles)){
} else {
}
} else {
$findFiles = $filesTable->patchEntity($findFiles, $data);
if($filesTable->save($findFiles)){
} else {
}
}
if ($this->Bookings->save($booking)) {
$this->Flash->success(__('The booking has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The booking could not be saved. Please, try again.'));
}
$this->set(compact('booking'));
$this->set('_serialize', ['booking']);
}
}
但是,在尝试使用Confirm功能时,我会在Sessions表中获得有关booking_id外键的完整性约束违规。我已经确定通过删除有关Files表的所有条件保存代码,该函数工作正常,但这意味着在需要时都不会创建newEntity for Files。
更简单的方法是我认为只包含新功能中的文件,但由于某些预订可能被取消,可能会有很多空的文件数据条目。
更新:包括模型和确认功能的视图和表单输入。
以下是BookingsController中的Confirm功能视图:
<?= $this->Form->create($booking) ?>
<fieldset>
<legend><?= __('Confirm Booking') ?></legend>
<?php
echo $this->Form->input('session.startdate', ['class'=>'form-control']);
echo $this->Form->input('session.enddate', ['class'=>'form-control']);
echo $this->Form->input('session.no_people', ['class'=>'form-control']);
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
各个表的模型。
预订:
public function initialize(array $config)
{
parent::initialize($config);
$this->table('bookings');
$this->displayField('id');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->hasOne('Sessions', [
'foreignKey' => 'booking_id'
]);
}
public function validationDefault(Validator $validator)
{
$validator
->integer('id')
->allowEmpty('id', 'create');
return $validator;
}
会话:
public function initialize(array $config)
{
parent::initialize($config);
$this->table('sessions');
$this->displayField('id');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->belongsTo('Bookings', [
'foreignKey' => 'booking_id',
'joinType' => 'INNER'
]);
$this->hasOne('Templates', [
'foreignKey' => 'session_id'
]);
}
public function validationDefault(Validator $validator)
{
$validator
->integer('id')
->allowEmpty('id', 'create');
$validator
->date('startdate')
->requirePresence('startdate', 'create')
->notEmpty('startdate');
$validator
->date('enddate')
->requirePresence('enddate', 'create')
->notEmpty('enddate');
$validator
->integer('no_people')
->requirePresence('no_people', 'create')
->notEmpty('no_people');
return $validator;
}
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->existsIn(['booking_id'], 'Bookings'));
return $rules;
}
文件:
public function initialize(array $config)
{
parent::initialize($config);
$this->table('files');
$this->displayField('id');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->belongsTo('Sessions', [
'foreignKey' => 'session_id',
'joinType' => 'INNER'
]);
}
public function validationDefault(Validator $validator)
{
$validator
->integer('id')
->allowEmpty('id', 'create');
$validator
->allowEmpty('link');
$validator
->allowEmpty('name');
return $validator;
}
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->existsIn(['session_id'], 'Sessions'));
return $rules;
}
答案 0 :(得分:1)
外键session_id
是必需属性(这就是文件无法保存的原因)。我已将功能更改为以下内容:
public function confirm($id = null)
{
$booking = $this->Bookings->get($id,[
'contain' => ['Sessions', 'Sessions.Files']
]);
if ($this->request->is(['patch', 'post', 'put'])) {
if($booking->session->file == null){ //checks for existing Files array
$template = $this->Bookings->Sessions->Files->newEntity(); //creates new Files entity if one doesn't exist for the associated session
$template->session_id = $booking->session->id; //fills in the foreign key with the currently active session primary key.
if($this->Bookings->Sessions->Templates->save($template)){ //saves the File entity
} else {
}
}
$booking = $this->Bookings->patchEntity($booking, $this->request->data,[
'contain' => ['Sessions', 'Sessions.Files']
]);
$fileTable = TableRegistry::get('Files');
$file = $fileTable->find('all',[
'contain' => ['Sessions'],
'conditions' => ['Sessions.booking_id' => $booking->id, 'Files.session_id' => $booking->session->id]
])->first();
if($file->session_id != $data['session']['id']){ //checks for any changes in session_id
$file->engineer_id = $data['session']['id']; //changes value to match if there isn't a match
$fileTable->save($template);
}
if ($this->Bookings->save($booking)) {
$this->Flash->success(__('The booking has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The booking could not be saved. Please, try again.'));
}
$this->set(compact('booking'));
$this->set('_serialize', ['booking']);
}
}
答案 1 :(得分:0)
这样的事情应该有效。如果存在id,Cake会将查询更改为UPDATE,否则使用INSERT。
public function confirm($id = null)
{
$booking = $this->Bookings->get($id, [
'contain' => ['Sessions' => ['Files']]
]);
if ($this->request->is(['patch', 'post', 'put'])) {
$booking = $this->Bookings->patchEntity($booking, $this->request->data, [
'associated' => ['Sessions' => ['associated' => ['Files']]]
]);
if ($this->Bookings->save($booking)) {
$this->Flash->success(__('The booking has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The booking could not be saved. Please, try again.'));
}
$this->set(compact('booking'));
$this->set('_serialize', ['booking']);
}
}