我有一个包含多对多类别和标签的内容模型。类别和标记存储在带有布尔tag
标志的同一表中:
category_id | name | tag
1 | Products | 0
2 | bestsellers | 1
我的内容模型具有如此定义的条件关系:
public function categories() {
return $this->belongsToMany('Foothing'Content'Z'Entities'Category'Eloquent'Category', 'content_content_categories', 'cid', 'tid')->where('tag', false);
}
public function tags() {
return $this->belongsToMany('Foothing'Content'Z'Entities'Category'Eloquent'Category', 'content_content_categories', 'cid', 'tid')->where('tag', true);
}
当 tag
标志在读取操作上正常工作时,即
$categories = Content::find(1)->categories;
$tags= Content::find(1)->tags;
它在sync
操作中没有按预期工作,实际上是以下代码
$content->categories()->sync(1, 2, 3);
将同步整个表格,无论tag
标志如何:标签将被销毁,我的内容将仅与类别 1、2、3 相关。
这种方法有什么不好吗?
我遇到过和你一样的情况,我玩的把戏就像
// the 1st sync will remove all the relationship to the category table
$content->categories()->sync([1, 2, 3]);
// the 2nd sync is to extends the relationship from the 1st
$content->tags()->syncWithoutDetaching([4, 5, 6]);
两者都来自同一个表,这意味着id
应该不同。这应该可以正常工作
当你调用Content::find(1)->categories
或任何其他关系时,它会通过Illuminate/Database/Eloquent/Model.php
文件line 2732
调用,其中此方法getRelationshipFromMethod
被调用和从模型中调用,例如它返回return $this->belongsToMany('Foothing'Content'Z'Entities'Category'Eloquent'Category', 'content_content_categories', 'cid', 'tid')->where('tag', false);
然后它在返回时调用getResults
并收集数据。
另一方面,当您调用$content->categories()
这是直接从Content
模型类访问的方法时,作为回报,它返回Illuminate'Database'Eloquent'Relations'BelongsToMany
类实例。
所以为了达到你的目的,你有
$content->categories()->where('content_content_categories.tag', false)
->sync([1, 2, 3]);//for syncing categories
$content->tags()->where('content_content_categories.tag', true)
->sync([1, 2, 3]);//for syncing tags
另外不要忘记同步方法接受ID数组或收集检查在这里 https://github.com/laravel/framework/blob/22c06c504067cc52787f9fc4b04de4e496442212/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php#L756