Laravel Eloquent ORM - 通过其他对象返回对象

时间:2014-09-02 18:36:03

标签: php laravel model eloquent relation

我有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;
    }
}

2 个答案:

答案 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关系,但显然你并不依赖它。