Laravel 5条件多对多同步()

时间:2016-01-14 11:27:01

标签: php laravel laravel-5 eloquent

我有一个包含多对多类别和标签的内容模型。 类别和标签与布尔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类相关。

这种做法有什么不好吗?

2 个答案:

答案 0 :(得分:0)

当您致电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

答案 1 :(得分:0)

我遇到过和你一样的情况,我在耍花招

// 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应该不同。这样应该可以解决问题