2013-06-24 84 views
0

我有「示例」表,「標記」表和中間的「examples_has_tags」表。所以一個例子可以有一些標籤,一個標籤可以屬於一些例子。Laravel 4過濾關係

在index.php中,我顯示了所有的例子和標籤列表。

$examples = Example::with('tags')->where('public', true)->get(); 

$tags = Tag::all(); 

return View::make('index')->with('examples', $examples) 
          ->with('tags',  $tags); 

完美地工作。 但是,我怎樣才能過濾標籤名稱的例子?我在stackoverflow上找到了一些東西:你應該在Example類中創建一個靜態方法,它返回我需要的東西。但是我顯示數據很麻煩。在上面的代碼中,我將它顯示爲:

@foreach ($examples as $example) 
     <div class="widgetbox"> 
      <h4 class="widgettitle">{{ $example->name }}</h4> 
      <div class="widgetcontent"> 
       {{ $example->body }} 
       <div class="tags-list"> 
        @foreach ($example->tags as $tag) 
         <span class="label label-info tag">{{ $tag->name }}</span> 
        @endforeach 
       </div> 
      </div> 
     </div> 
    @endforeach 

有沒有簡單的方法來做到這一點?我發現了一些有關篩選集合,但沒有例子

更新

我找到了一個解決方案:

$examples = $examples->filter(function($example) { 
     $tags = $example->tags->toArray(); 
     foreach ($tags as $tag) { 
      if ($tag["name"] == Input::get('tag')) return true; 
     } 
     return false; 
    }); 

UPDATE2

試圖做到這一點沒有PHP過濾,但我不能得到屬於一個例子的標籤:

$tagId = Tag::where('name', '=', Input::get('tag'))->first()->id; 

     $examples = Example::with('tags') 
          ->join('examples_has_tags', 'examples_has_tags.example_id', '=', 'examples.id') 
          ->where('examples_has_tags.tag_id', '=', $tagId)->get(); 

$例子不包含標籤列表(它實際上是空的)

+0

我的替代(in_array)方法怎麼樣,請您檢查一下嗎? –

+0

沒有工作,$ example-> tags-> toArray()不僅返回數組(「tagName1」,「tagName2」...)所以...我試過array_pluck但沒有成功(不知道爲什麼id didn不爲我工作)。 – Victor

+0

您的解決方案是否正常工作? –

回答

0

如下(Eager Loading

型號你可以這樣做:(例)

class Example extends Eloquent { 
    public function tags() 
    { 
     return $this->hasMany('Tag'); 
    } 
} 

現在查詢:

$examples = Example::with(array('tags' => function($query) 
{ 
    $query->where('name', '=', 'someName'); 
}))->get(); 

更新:

$examples = $examples->filter(function($example) { 
    $tags = $example->tags->toArray(); 
    return in_array(Input::get('tag'), $tags) ?: FALSE; 
}); 
+0

據我所知,我會得到所有的例子,在每個例子中,我將過濾標籤。但這不是我想要得到的 - 我想過濾示例列表本身。我想我已經嘗試了你的解決方案,但我會在幾個小時內檢查,謝謝 – Victor

+0

也許我誤解了,反正,歡迎:-) –

+0

在我的文章(我更新了)看看我的解決方案。似乎它的工作 – Victor

0

你應該做的是創建一個連接,然後創建你想要的東西where子句。根據您希望如何通過標籤篩選,你可以做這樣的事情:

首先提取有效標籤ID:

$tagIDs = array_pluck(Tag::whereIn('name', array(
    'tag1', 
    'tag2', 
    'tag3', 
))->toArray(), 'id'); 

然後通過TAG_ID過濾的例子:

return Example::select('examples.*') 
    ->join('examples_has_tags', 'examples.id', '=', DB::raw('examples_has_tags.example_id')) 
    ->whereIn(DB::raw('examples_has_tags.tag_id'), $tagIDs) 
    ->get(); 

有可能(也可能是)這樣做的更有效的方法,但這是我如何接近它。

+0

我的解決方案呢(我更新了我的文章)?似乎它的工作 – Victor

+1

是的,這個你的解決方案應該工作。但是,有一個區別。你正在使用PHP進行過濾。這比數據庫引擎慢,因爲它沒有被優化來做到這一點。 此外,您將所有示例提取到腳本中,然後再開始過濾。想象一下擁有一個擁有1.000.000記錄的數據庫......它會變得非常緩慢。如果讓數據庫引擎執行過濾,則不會(真的)出現此問題。 – DerLola

+0

我想你是對的,但是我怎樣才能得到每個例子的標籤列表?看看我的帖子update2。由於我只用一個標籤進行過濾,因此我略微更改了查詢,並且不使用DB :: raw,因爲它沒有這個工作。我得到正確的例子,但當我循環他們,我嘗試顯示每個示例的標籤列表(如@foreach($ example->標籤爲$標籤)標籤數組爲空...... – Victor