我有三个表,Articles
、Comments
和Tags
。
Tags
属于Articles
和Comments
。
$this->Articles->patchEntity($entity, $this->request->getData(), [
'associated' => ['Comments.Tags']
]);
出现以下错误:
SQLSTATE[HY000]: General error: 1364 Field 'article_id' doesn't have a default value
Please try correcting the issue for the following table aliases:
CommentsArticles
但是如果我只用'associated' => ['Comments']
保存它就可以保存Article
并使用连接表关联Comments
,只是不保存任何Tags
.
Articles
表具有以下关联:
$this->hasMany('Tags', [
'foreignKey' => 'article_id'
]);
$this->belongsToMany('Comments', [
'foreignKey' => 'article_id',
'targetForeignKey' => 'comment_id',
'joinTable' => 'comments_articles'
]);
Comments
表具有以下关联:
$this->hasMany('Tags', [
'foreignKey' => 'comment_id'
]);
$this->belongsToMany('Articles', [
'foreignKey' => 'comment_id',
'targetForeignKey' => 'article_id',
'joinTable' => 'comments_articles'
]);
Tags
表具有以下关联:
$this->belongsTo('Comments', [
'foreignKey' => 'comment_id',
'joinType' => 'INNER'
]);
$this->belongsTo('Articles', [
'foreignKey' => 'article_id',
'joinType' => 'INNER'
]);
这是修补后的实体看起来像这样。
object(AppModelEntityArticle) {
'title' => 'example article name',
'users' => [
'_ids' => []
],
'comments' => [
(int) 0 => object(AppModelEntityComment) {
'id' => (int) 1,
'content' => 'this is a comment',
'tags' => [
(int) 0 => object(AppModelEntityTag) {
'name' => 'example tag name',
'[new]' => true,
'[accessible]' => [
'comment_id' => true,
'article_id' => true,
'comment' => true,
'article' => true
],
'[dirty]' => [
'name' => true
],
'[original]' => [],
'[virtual]' => [],
'[hasErrors]' => false,
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Tags'
}
],
'[new]' => false,
'[accessible]' => [
'content' => true,
'tags' => true,
'articles' => true
],
'[dirty]' => [
'tags' => true
],
'[original]' => [
'tags' => [
(int) 0 => [
'name' => '0'
]
]
],
'[virtual]' => [],
'[hasErrors]' => false,
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Comments'
}
],
'[new]' => true,
'[accessible]' => [
'title' => true,
'tags' => true,
'comments' => true,
'users' => true
],
'[dirty]' => [
'title' => true,
'users' => true,
'comments' => true
],
'[original]' => [
'users' => []
],
'[virtual]' => [],
'[hasErrors]' => false,
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Articles'
}
CaekPHP 不支持,它只能在一个方向上填充直接关联的外键。例如,您可以:
-
预填充外键字段(当然,只有在文章和/或注释已经存在时才有效(
-
使用文章和评论记录的主键分别手动保存标签
-
创建关联类,在保存文章时将文章主键传递到选项中,并在保存标记时使用该键填充
article_id
字段 -
挂钩到表级别的保存过程以传递文章主键并用它填充标签
下面是后一种解决方案的快速而肮脏的示例,它还应该让您了解它如何在关联级别工作:
在ArticlesTable
:
public function beforeSave(
CakeEventEvent $event,
CakeDatasourceEntityInterface $entity,
ArrayObject $options
) {
if (isset($options['Articles.id'])) {
unset($options['Articles.id']);
}
}
protected function _onSaveSuccess($entity, $options)
{
if ($options['_primary']) {
$options['Articles.id'] = $entity->get('id');
}
return parent::_onSaveSuccess($entity, $options);
}
在TagsTable
:
public function beforeSave(
CakeEventEvent $event,
CakeDatasourceEntityInterface $entity,
ArrayObject $options
) {
if (!$options['_primary'] &&
isset($options['Articles.id'])
) {
$entity->set('article_id', $options['Articles.id']);
}
}