我有3个型号:商店,产品和标签。商店和产品是一对多的关系,而产品是标签的多对多。
我想为每个商店抓取所有唯一标签(因为许多产品可以有相同的标签)。
class Shop extends Eloquent {
public function products() {
return $this->hasMany('Product');
}
}
class Product extends Eloquent {
public function shop() {
return $this->belongsTo('Shop');
}
public function tags() {
return $this->belongsToMany('Tag');
}
}
class Tag extends Eloquent {
public function products() {
return $this->belongsToMany('Product');
}
}
我提出的解决方案之一就是关注。问题是我没有获得唯一标签。有一个解决方案可以让另一个foreach循环通过标记数组并比较标记对象中的id。我想优化一下,您认为更好/更清洁的解决方案是什么?
class Shop extends Eloquent {
...
public function getTagsAttribute() {
$tags = array();
foreach($this->products as $product)
{
foreach ($product->tags as $tag)
{
$tags[] = $tag;
}
}
return $tags;
}
}
答案 0 :(得分:1)
也许您可以试试这个:
$tags = Tag::has('products')->get();
这将返回绑定到任何Tags
的所有Product
。如有必要,您也可以使用distinct
,但我认为在这种情况下没有必要:
$tags = Tag::has('products')->distinct()->get();
更新:然后你可以尝试这样的事情:
public function getTagsAttribute()
{
$shopId = $this->id;
$tags = Tag::whereHas('products', function($query) use($shopId) {
$query->where('products.shop_id', $shopId);
})->get();
return $tags;
}
答案 1 :(得分:1)
@ WereWolf的方法对你有用,但这里有一个适用于所有关系的技巧:
$shop = Shop::with(['products.tags' => function ($q) use (&$tags) {
$tags = $q->get()->unique();
}])->find($someId);
// then:
$tags; // collection of unique tags related to your shop through the products
请注意,每个$tags
都会有pivot
属性,因为它是belongsToMany
关系,但显然你并不依赖它。