2014-09-02 61 views
0

我有3個模型:Shop,Products和Tags。商店和產品是一對多的關係,產品可以標籤爲多對多。Laravel Eloquent ORM - 通過另一個對象返回對象

我想抓住每個店鋪所有獨特的標籤(因爲許多產品可以有相同的標籤)。

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

回答

1

@狼人的方法將爲你工作,但這裏有一個技巧,將適用於所有的關係:

$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關係,但顯然你不依賴於此。

+0

更好的解決方案 – 2014-09-02 22:48:22

+0

是的,值得注意的是:它執行額外的查詢來獲取這些標籤。這是缺點,但它仍然是實現你所需要的最簡單的解決方案。 – 2014-09-02 22:51:42

1

也許你可以試試這個:

$tags = Tag::has('products')->get(); 

這將返回所有綁定到任何ProductTags。如果必要的話,你也可以使用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; 
} 
+0

我想獲得屬於特定商店的唯一標籤..有一個模型 – 2014-09-02 18:44:30

+0

檢查更新的答案。 – 2014-09-02 19:02:34

+0

很棒的工作,非常感謝。這是我一直在尋找 – 2014-09-02 22:34:29