具有属于两个更高模型的深度关联的保存模型
saving model with deep association belonging to both higher models
我有三个 table、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
加入 table 关联,只是不保存任何 Tags
.
Articles
table 有这些关联:
$this->hasMany('Tags', [
'foreignKey' => 'article_id'
]);
$this->belongsToMany('Comments', [
'foreignKey' => 'article_id',
'targetForeignKey' => 'comment_id',
'joinTable' => 'comments_articles'
]);
Comments
table 有这些关联:
$this->hasMany('Tags', [
'foreignKey' => 'comment_id'
]);
$this->belongsToMany('Articles', [
'foreignKey' => 'comment_id',
'targetForeignKey' => 'article_id',
'joinTable' => 'comments_articles'
]);
和Tags
table有这些关联:
$this->belongsTo('Comments', [
'foreignKey' => 'comment_id',
'joinType' => 'INNER'
]);
$this->belongsTo('Articles', [
'foreignKey' => 'article_id',
'joinType' => 'INNER'
]);
这是修补后的实体,看起来像这样。
object(App\Model\Entity\Article) {
'title' => 'example article name',
'users' => [
'_ids' => []
],
'comments' => [
(int) 0 => object(App\Model\Entity\Comment) {
'id' => (int) 1,
'content' => 'this is a comment',
'tags' => [
(int) 0 => object(App\Model\Entity\Tag) {
'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 不支持,它只能在一个方向上填充直接关联/ 的外键。例如,您可以:
预填充外键字段(当然只有当文章and/or评论已经存在时才有效)
使用文章和评论记录的主键分别手动保存标签
创建关联 类,在保存文章时将文章主键传递到选项中,并在保存标签时使用它来填充 article_id
字段
挂钩 table 级别的保存过程以传递文章主键并用它填充标签
这是后一种解决方案的一个简单粗暴的示例,它还应该让您了解它如何在关联级别上工作:
在ArticlesTable
中:
public function beforeSave(
\Cake\Event\Event $event,
\Cake\Datasource\EntityInterface $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(
\Cake\Event\Event $event,
\Cake\Datasource\EntityInterface $entity,
\ArrayObject $options
) {
if (!$options['_primary'] &&
isset($options['Articles.id'])
) {
$entity->set('article_id', $options['Articles.id']);
}
}
我有三个 table、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
加入 table 关联,只是不保存任何 Tags
.
Articles
table 有这些关联:
$this->hasMany('Tags', [
'foreignKey' => 'article_id'
]);
$this->belongsToMany('Comments', [
'foreignKey' => 'article_id',
'targetForeignKey' => 'comment_id',
'joinTable' => 'comments_articles'
]);
Comments
table 有这些关联:
$this->hasMany('Tags', [
'foreignKey' => 'comment_id'
]);
$this->belongsToMany('Articles', [
'foreignKey' => 'comment_id',
'targetForeignKey' => 'article_id',
'joinTable' => 'comments_articles'
]);
和Tags
table有这些关联:
$this->belongsTo('Comments', [
'foreignKey' => 'comment_id',
'joinType' => 'INNER'
]);
$this->belongsTo('Articles', [
'foreignKey' => 'article_id',
'joinType' => 'INNER'
]);
这是修补后的实体,看起来像这样。
object(App\Model\Entity\Article) {
'title' => 'example article name',
'users' => [
'_ids' => []
],
'comments' => [
(int) 0 => object(App\Model\Entity\Comment) {
'id' => (int) 1,
'content' => 'this is a comment',
'tags' => [
(int) 0 => object(App\Model\Entity\Tag) {
'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 不支持,它只能在一个方向上填充直接关联/ 的外键。例如,您可以:
预填充外键字段(当然只有当文章and/or评论已经存在时才有效)
使用文章和评论记录的主键分别手动保存标签
创建关联 类,在保存文章时将文章主键传递到选项中,并在保存标签时使用它来填充
article_id
字段挂钩 table 级别的保存过程以传递文章主键并用它填充标签
这是后一种解决方案的一个简单粗暴的示例,它还应该让您了解它如何在关联级别上工作:
在ArticlesTable
中:
public function beforeSave(
\Cake\Event\Event $event,
\Cake\Datasource\EntityInterface $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(
\Cake\Event\Event $event,
\Cake\Datasource\EntityInterface $entity,
\ArrayObject $options
) {
if (!$options['_primary'] &&
isset($options['Articles.id'])
) {
$entity->set('article_id', $options['Articles.id']);
}
}