我有一个带有用户个人资料的表格。每个用户都可以编辑自己的个人资料,并且可以添加和编辑课程(用户实际上是前者)
例如,当我尝试编辑个人资料时,我有两个特定的角色,它们是某种标签。用户可以输入他期望的技能和他的实际技能。为了自动完成每个技能字段,我使用了另一个称为技能的表。 为了将两者链接在一起,我使用了第三个表Skills_map。 这两个技能字段可以在个人资料表格和课程表格中找到。 我想对课程和个人资料上下文使用相同的数据透视表。
这是我的表表示形式
1- Skills_map表(数据透视表) skill_id |整数(11) content_type | varchar(255)(用于“ polymorphysm”,上下文示例:Profiles.desiredSkills或Courses.desiredSkills-我使用模型来命名,然后使用技能类型) content_type_id |整数(11) 创建|约会时间 修改|日期时间
2-配置文件表 account_type | int(11) first_name | varchar(255) last_name | varchar(255) 性别| varchar(255) slug | varchar(255) 主动| int(11) 创建|日期时间 修改|日期时间
3-技能表(用于自动完成) 活跃整数(1) 名称| varchar(255) 子弹| varchar(255) 创建|约会时间 修改|日期时间
4门课程表 标题| varchar(255) 子弹| varchar(255) 描述|文字
我的个人资料表包含我的关系,我已经向我的belongsToMany添加了条件,如您所见,稍后将在我的“查找包含”查询中使用。
public function initialize(array $config){
parent::initialize($config);
$this->setTable('profiles');
$this->setDisplayField('id');
$this->setPrimaryKey('id');
$this->addBehavior('Timestamp');
$this->hasOne('Users')->setForeignKey('profile_id');
$this->belongsToMany('Businesses', [
'foreignKey' => 'profile_id',
'targetForeignKey' => 'business_id',
'joinTable' => 'businesses_profiles'
]);
$this->belongsToMany('Schedules', [
'foreignKey' => 'profile_id',
'targetForeignKey' => 'schedule_id',
'joinTable' => 'schedules_profiles'
]);
$this->belongsToMany('ActualSkills', [
'className' => 'Skills',
'foreignKey' => 'content_type_id',
'targetForeignKey' => 'skill_id',
'joinTable' => 'skills_map',
'conditions' => ['SkillsMap.content_type' => 'Profiles.ActualSkills'],
]);
$this->belongsToMany('DesiredSkills', [
'className' => 'Skills',
'foreignKey' => 'content_type_id',
'targetForeignKey' => 'skill_id',
'joinTable' => 'skills_map',
'conditions' => ['SkillsMap.content_type' => 'Profiles.DesiredSkills'],
]);
}
我的SkillsTable关系
public function initialize(array $config) {
parent::initialize($config);
$this->setTable('skills');
$this->setDisplayField('name');
$this->setPrimaryKey('id');
$this->addBehavior('Timestamp');
$this->belongsToMany('Profiles', [
'foreignKey' => 'skill_id',
'targetForeignKey' => 'content_type_id',
'joinTable' => 'skills_map',
'through' => 'SkillsMap'
]);
}
我的技能地图表
public function initialize(array $config){
parent::initialize($config);
$this->setTable('skills_map');
$this->setDisplayField('id');
$this->setPrimaryKey('id');
$this->addBehavior('Timestamp');
$this->belongsTo('Skills');
$this->belongsTo('Profiles');
}
我的个人资料表单(标签的课程形式将相似)
<div class="card card-profile-skills py-4 mt-4">
<div class="card-body">
<fieldset>
<div class="form-row">
<div class="col">
<div class="form-group">
<label for="description"><?= __('edit_profile_actual_skills_label') ?></label>
<?=
$this->Form->input('actual_skills._ids', [
'label' => false,
'multiple' => 'multiple',
'type' => 'select',
'data-js-multiple-skills-select' => '',
'data-ajax-url' => $this->Url->build(['_name' => 'get_ajax_skills_list_path'], true),
'empty' => 'placeholder',
'options' => $selectedActualSkills,
'default' => array_keys($selectedActualSkills),
]);
?>
</div>
</div>
</div>
<div class="form-row mt-4">
<div class="col">
<div class="form-group">
<label for="description"><?= __('edit_profile_desired_skills_label') ?></label>
<?=
$this->Form->input('desired_skills._ids', [
'label' => false,
'multiple' => 'multiple',
'type' => 'select',
'data-js-multiple-skills-select' => '',
'data-ajax-url' => $this->Url->build(['_name' => 'get_ajax_skills_list_path'], true),
'empty' => 'placeholder',
'options' => $selectedDesiredSkills,
'default' => array_keys($selectedDesiredSkills),
]);
?>
</div>
</div>
</div>
</fieldset>
</div>
还有我的控制器
public function edit($hash = null){
$profile = $this->Profiles->findByHash($hash)->contain([
'ActualSkills' => function ($q) {
return $q;
//return $q->where(['Profiles.is_published' => true]); /* @ todo: finish request to fit with context skills */
},
'DesiredSkills' => function ($q) {
return $q;
//return $q->where(['Profiles.is_published' => true]); /* @ todo: finish request to fit with context skills */
}
])->formatResults(function($results){
return $results->map(function($row){
$row->data = json_decode($row->data);
return $row;
});
})->first();
$redirect = ['_name' => 'home'];
$associated = [
'associated' => [
'ActualSkills',
'ActualSkills._joinData',
'DesiredSkills',
'DesiredSkills._joinData',
]
];
if (!$profile || !$profile->isProfileOwner($this->_currentUser)) {
$this->Flash->error(__('Retourner une 404'));
}
$selectedActualSkills = $this->Util->generateList($profile->actual_skills, ['key' => 'id', 'value' => 'name']);
$selectedDesiredSkills = $this->Util->generateList($profile->desired_skills, ['key' => 'id', 'value' => 'name']);
if ($this->request->is(['patch', 'post', 'put'])) {
$profile = $this->Profiles->patchEntity($profile, $this->request->getData(), $associated);
$profile->set('slug');
if ($this->Profiles->save($profile, $associated)) {
/* <BEGIN> Update Pivot table */
if($profile->actual_skills)
{
foreach($profile->actual_skills as $skill)
{
$pivotRow = $this->Profiles->SkillsMap->findBySkillId($skill->id)->where([
'content_type_id' => $profile->id
])->first();
$pivotRow->content_type = $this->name . '.ActualSkills' ;
$this->Profiles->SkillsMap->save($pivotRow);
}
}
/* <END> Update Pivot table */
if (isset($profile->save_btn)) {
$redirect = ['_name' => 'my_profile_path', 'hash' => $profile->hash];
}
$this->Flash->success(__('edit_profile_success'));
return $this->redirect($redirect);
}
$this->Flash->error(__('edit_profile_error'));
}
$this->set(compact('profile', 'selectedActualSkills', 'selectedDesiredSkills'));
}
因此,保存时需要填充我的列content_type。我想使用_joinData,但是我在Cake图书中读了那本书,但无法使用。 我说的是在将条件放入表链接(content_type以描述个人资料,从个人资料或课程形式中)之前,先进行条件查询,再以示例方式检索技能领域中的选定选项。但是,如果在编辑表单时未保存数据,则查询将无法进行。 我不想为技能创建三个表,任何可能只用一个表就可以达到目的吗?
非常感谢您的帮助! ;-)
洛朗。