php belongsto,更新belongsToMany关联数据

博客内容涉及使用CakePHP框架进行数据库操作时遇到的问题。作者在尝试编辑人员信息并更新其角色关联时,遇到保存失败的错误。问题在于保存过程中需要提供person_to_role.person_id和role.name的值,而系统似乎无法正确识别这些信息。作者尝试了多种解决方案,包括调整关联设置和验证规则,但更新操作仍生成了INSERT查询而非UPDATE,导致唯一约束违例错误。目前,作者能够通过验证,但保存过程产生了错误的数据库操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SQL H3>

--person

+-------------+-------------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+-------------+-------------+------+-----+---------+----------------+

| ID | int(11) | NO | PRI | NULL | auto_increment |

| NICK_NAME | varchar(16) | YES | | NULL | |

| FIRST_NAME | varchar(24) | NO | | NULL | |

| MIDDLE_NAME | varchar(8) | YES | | NULL | |

| LAST_NAME | varchar(24) | NO | | NULL | |

| BIRTH_DATE | date | NO | | NULL | |

| GENDER | varchar(8) | NO | | NULL | |

+-------------+-------------+------+-----+---------+----------------+

-- role

+-------------+--------------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+-------------+--------------+------+-----+---------+----------------+

| ID | int(11) | NO | PRI | NULL | auto_increment |

| NAME | varchar(24) | NO | | NULL | |

| DESCRIPTION | varchar(100) | YES | | NULL | |

+-------------+--------------+------+-----+---------+----------------+

--person_to_role

+-------------+--------------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+-------------+--------------+------+-----+---------+----------------+

| ID | int(11) | NO | PRI | NULL | auto_increment |

| PERSON_ID | int(11) | NO | MUL | NULL | |

| ROLE_ID | int(11) | NO | MUL | NULL | |

| DESCRIPTION | varchar(100) | YES | | NULL | |

+-------------+--------------+------+-----+---------+----------------+

PersonTable模型 h3>

公共函数初始化(数组$配置)

{

父::初始化($配置);

$this->setTable('person');

$this->setDisplayField('ID');

$this->setPrimaryKey('ID');

// define relations

$this->belongsToMany('Role', [

'joinTable'=> 'person_to_role',

'foreignKey' => 'PERSON_ID'

]);

}

人员控制器 - >编辑() h3>

public function edit($id = null)

{

$person = $this->Person->get($id, [

'contain' => ['role']

]);

$this->set('roles', $this->Person->Role->find('list'));

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

$person = $this->Person->patchEntity($person, $this->request->getData());

if ($this->Person->save($person)) {

$this->Flash->success(__('The person has been saved.'));

return $this->redirect(['action' => 'index']);

}

$errors = print_r($person->errors(),1);

$this->Flash->error(__('The person could not be saved. Please, try again.

'. $errors .'
'),['escape'=> false]);

}

$this->set(compact('person'));

$this->set('_serialize', ['person']);

}

edit.ctp表单字段 h3>

echo $this->Form->control('NICK_NAME');

echo $this->Form->control('FIRST_NAME');

echo $this->Form->control('MIDDLE_NAME');

echo $this->Form->control('LAST_NAME');

echo $this->Form->control('BIRTH_DATE');

echo $this->Form->control('GENDER',['type'=>'select','options'=>[''=> '-

Please Select -', 'Male'=>'Male','Female'=>'Female']]);

Assigned roles

...

<?php foreach ($person->role as $k=>$role) { ?>

<?php

echo $this->Form->input("role.$k._joinData.ID",['type'=>'hidden','value'=>$person->role[$k]['_joinData']['ID']]);

echo $this->Form->input("role.$k._joinData.ROLE_ID",['value'=>$role-

>ID,'options'=>$roles,'templates'=>['formGroup' =>'{{input}}']])

?>

<?php echo $this->Form->input("role.$k._joinData.DESCRIPTION", ['value'=>$person->role[$k]['_joinData']['DESCRIPTION'],'templates'=>

['formGroup' =>'{{input}}']]); ?>

...这给了我以下的POST数据:

'NICK_NAME' => 'Johny',

'FIRST_NAME' => 'John',

'MIDDLE_NAME' => 'J.',

'LAST_NAME' => 'Smith',

'BIRTH_DATE' => '1961-01-01',

'GENDER' => 'Male',

'role' => [

(int) 0 => [

'_joinData' => [

'ID' => '1',

'ROLE_ID' => '5',

'DESCRIPTION' => 'person role description'

]

]

]

]但更新失败,出现以下错误:

这个人不能被保存。请再试一次。

Array

(

[role] => Array

(

[0] => Array

(

[NAME] => Array

(

[_required] => This field is required

)

[_joinData] => Array

(

[PERSON_ID] => Array

(

[_required] => This field is required

)

)

)

)

)它要求提供person_to_role.person_id这是外键(它应该知道当前的人员ID),并且需要role.name的值。

我是否将我的关联设置错了?任何帮助表示赞赏。

UPDATE 2017-08-20 h2>

仍然没有去,试图从文档和其他互联网资源的所有可能的变化。目前,我能够将验证传递给save操作,但会生成INSERT查询而不是UPDATE,并在唯一约束违例时生成错误。

我有person.ID和person_to_role.ID可供使用:

protected $_accessible = [

'*' => true,

'ID' => true

];我的POST数据如下所示:

[

'NICK_NAME' => '',

'FIRST_NAME' => 'test',

'MIDDLE_NAME' => '',

'LAST_NAME' => 'user',

'BIRTH_DATE' => '1996-10-01',

'GENDER' => 'Male',

'role' => [

(int) 0 => [

'_joinData' => [

'ID' => '153',

'DESCRIPTION' => 'test edited text'

],

'ID' => '2'

]

]

]我试了两次,_joinData中有和没有person_to_role记录ID,结果相同:

INSERT INTO person_to_role (PERSON_ID, ROLE_ID, DESCRIPTION)

VALUES (129, 2, 'test edited text')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值