2016-01-14 33 views
3

我有一个内容模型与多对多的类别和标签。 分类和标签都存储在同一个表用布尔tag标志:Laravel 5条件多对多同步()

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

是不是有什么不好用这种方法?

回答

0

当你调用Content::find(1)->categories或任何其他关系,它就会通过Illuminate/Database/Eloquent/Model.php文件line 2732其中这些方法getRelationshipFromMethod被称为&从模型e.g称这将返回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

收集检查数组这似乎并不工作伴侣,当我执行sync()这个删除查询被执行:'从'content_content_categories'中删除,其中'cid' =?和'tid'在(?,?,?)'中。正如你所看到的,在标准中没有使用标签字段的证据。 – brazorf

+0

我想我想要做的事是不可能使用sync()而不更改数据库结构,因为查询中涉及的唯一表是没有标记列信息的数据透视表。 – brazorf