CakePHP 3:编辑belongsToMany模型时预选复选框

3

我有一个工作坊模型,通过workshops_speakers属于许多演讲者:

class WorkshopsTable extends Table
{
    public function initialize(array $config) 
    {
        $this->table('workshops');
        $this->displayField('title');
        $this->primaryKey(['id']);

        $this->belongsTo('Times', [
            'foreignKey' => 'time_id',
            'joinType' => 'INNER'
        ]);

        $this->belongsToMany('Speakers', [
            'foreignKey' => 'workshop_id',
            'targetForeignKey' => 'speaker_id',
            'joinTable' => 'speakers_workshops'
        ]);
    }
}

创建讲习班、指派演讲者并为其安排时间都很顺利。然而,如果我想编辑一个讲习班,可能的演讲者会出现,但是指定的演讲者不会自动预先选定(如果我在编辑时仅选择了一些演讲者,则保存将起作用-指定的时间也会自动预先选定)。我的编辑.ctp输入如下:

<?= $this->Form->create($workshop); ?>
...
echo $this->Form->input('time_id', ['type' => 'select', 'multiple' => false, 'class' => 'form-control']);
echo $this->Form->input('speakers._ids', ['multiple' => 'checkbox']);

WorkshopsController::edit()

/**
 * Edit method
 *
 * @param string|null $id Workshop id.
 * @return void Redirects on successful edit, renders view otherwise.
 * @throws \Cake\Network\Exception\NotFoundException When record not found.
 */
public function edit($id = null)
{
    $workshop = $this->Workshops->get($id, [
        'contain' => ['Speakers']
    ]);
    if ($this->request->is(['patch', 'post', 'put'])) {
        $workshop = $this->Workshops->patchEntity($workshop, $this->request->data);
        if ($this->Workshops->save($workshop)) {
            $this->Flash->success('The workshop has been saved.');
            return $this->redirect(['action' => 'index']);
        } else {
            $this->Flash->error('The workshop could not be saved. Please, try again.');
        }
    }

    $times = $this->Workshops->Times->find('list');
    $speakers = $this->Workshops->Speakers->find('list');

    $this->set(compact('workshop', 'times', 'speakers'));
    $this->set('_serialize', ['workshop']);
}

在我的 Workshop 实体中,我还将 "speakers" 指定为可访问的:
protected $_accessible = [
    'title' => true,
    'date' => true,
    'description' => true,
    'type' => true,
    'sort' => true,
    'meta' => true,
    'time_id' => true,
    'speakers' => true,
];

我在使用虚拟字段来显示讲者的名字和姓氏在复选框下方。在SpeakersTable::initialize()中:

$this->displayField('full_name');

在扬声器实体中:
protected function _getFullName() {
    return $this->_properties['first_name'].' '.$this->_properties['last_name'];
}

简述:显示可用演讲者列表,但在编辑研讨会时未预先选择与研讨会相关的演讲者。其他所有功能都正常。


请展示您完整的edit()操作代码和Form::create()调用。另外,顺便提一下,您的第一个代码示例有问题,方法调用应该在initialize()方法中。 - ndm
添加了edit()(由cake bake创建)和Form::create()调用。缺少的initialize方法只是一个复制粘贴错误。 - user2018648
1
你后来添加的“contain”选项值是否也是一个复制粘贴错误呢?因为除此之外我没发现其他问题。 - ndm
我一段时间前添加了contain选项,但它并没有改变任何东西。创建新的研讨会时,数据被正确保存:在列出研讨会时,我可以获取相关的演讲者。 - user2018648
1
我的错:确实是contain选项。添加了该选项后,我还通过“val”手动分配相关的扬声器来更改表单输入调用,但不幸的是,由于给定的数组为空,这会重置选择。删除了“val”,现在它可以正常工作了。抱歉! - user2018648
1个回答

3
问题已解决,我忘记在WorkshopsController::edit()中添加contain选项的值。
$workshop = $this->Workshops->get($id, [
    'contain' => ['Speakers']
]);

我没有看到,添加选项后它是否工作,因为我同时尝试在edit.ctp手动选择复选框,这会重置它们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接