cakephp - Updating belongsToMany association data -
i setting form updates person
, associated person_to_role
tables, person_to_role
intermediate table links person
role
in n..n relationship. role
has predefined list of roles, shouldn't modified person's scope.
i need update role_id
, description
in person_to_role
table , add/remove records.
sql
--person +-------------+-------------+------+-----+---------+----------------+ | field | type | null | key | default | | +-------------+-------------+------+-----+---------+----------------+ | 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 | | +-------------+--------------+------+-----+---------+----------------+ | 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 | | +-------------+--------------+------+-----+---------+----------------+ | 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 model
public function initialize(array $config) { parent::initialize($config);
$this->settable('person'); $this->setdisplayfield('id'); $this->setprimarykey('id'); // define relations $this->belongstomany('role', [ 'jointable'=> 'person_to_role', 'foreignkey' => 'person_id' ]); }
person controller -> edit()
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 not saved. please, try again.<br><pre>'. $errors .'</pre>'),['escape'=> false]); } $this->set(compact('person')); $this->set('_serialize', ['person']); }
edit.ctp form fields
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 $k=>$role) { ?> <tr><td><?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}}']]) ?></td><td> <?php echo $this->form->input("role.$k._joindata.description", ['value'=>$person->role[$k]['_joindata']['description'],'templates'=> ['formgroup' =>'{{input}}']]); ?></td></tr> <?php } ?> ...
this gives me following post data:
'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' ] ] ] ]
but update fails following errors:
the person not saved. please, try again.
array ( [role] => array ( [0] => array ( [name] => array ( [_required] => field required ) [_joindata] => array ( [person_id] => array ( [_required] => field required ) ) ) ) )
it asks provide person_to_role.person_id
foreignkey (it should know current person id), , wants value role.name
. did set association wrong? appreciated.
update 2017-08-20
still no go, tried possible variations docs , other internet resources. able pass through validation save
action, insert
query generated instead of update
, errors out on unique constraint violation.
i have person.id
, person_to_role.id
accessible:
protected $_accessible = [ '*' => true, 'id' => true ];
my post data looks this:
[ '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' ] ] ]
i tried both, , without person_to_role
record id in _joindata
, same result:
insert person_to_role (person_id, role_id, description) values (129, 2, 'test edited text')
while trying different methods, including using 'through' association, had following lines added persontoroletable.php
model:
$this->belongsto('person'); $this->belongsto('role');
after commenting these out, worked expected, able save updates add new , delete existing records in join table.
Comments
Post a Comment