2015-05-29 106 views
0

我有三個表。使用Laravel查詢多對多關係和更多數據(流明/雄辯)

表1:posts //存儲用戶的Twitter的職位
表2:tags //存儲在Twitter的職位使用
表3中的標籤:post_tag //樞軸表

現在,我想要輸入一個tag,例如'yolo'並獲取所有包含此標籤的帖子。這是相當容易的,我已經做了這樣的

類崗位:

/** 
* Get the tags associated with the post 
* 
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany 
*/ 
public function tags() 
{ 
    return $this->belongsToMany('App\Models\Tag')->get(['tag']); 
} 

類標籤:

/** 
* Get the posts associated with the given tag 
* 
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany 
*/ 
public function posts() 
{ 
    return $this->belongsToMany('App\Models\Post'); 
} 

訪問數據:

/** @var Tag $tag */ 
try { 
    $tag = Tag::where('tag', urldecode($passedTag))->firstOrFail(); 
    return response()->json(['posts' => $tag->posts->toArray()]); 
} catch (ModelNotFoundException $e) { 
    return response()->json(['errors' => 'No query results for: '. $passedTag]); 
} 

然而,是什麼我希望addaly做,也是獲得所有已用於該帖子的其他標籤。例如。一個帖子有標籤yoloswag。現在,當用戶輸入yolo時,我希望應用程序顯示標記爲yolo的所有帖子,但還會顯示帖子具有的所有其他標記,在此示例中爲swag。我已經這樣做了

/** @var Tag $tag */ 
try { 
    $tag = Tag::where('tag', urldecode($passedTag))->firstOrFail(); 
    $posts = $tag->posts; 
    $fData = []; 
    foreach ($posts as $index=>$post) { 
     /** @var Post $post */ 
     $fData[$index] = $post->toArray(); 
     $fData[$index]['tags'] = $post->tags(); 
    } 
    return response()->json(['posts' => $fData]); 
} catch (ModelNotFoundException $e) { 
    return response()->json(['errors' => 'No query results for: '. $passedTag]); 
} 

但是因爲我是Laravel(Lumen)的新手,所以我確信有一個更快的方法來做到這一點。任何建議,我會如何做到這一點更高性能?謝謝! :)

回答

1

你可以Eager load所有需要的關係。它們也將顯示在toArray之中。

/** @var Tag $tag */ 
try { 
    return response()->json([ 
     'posts' => Tag::with('posts')->with([ 
      'posts.tags' => function ($query) { 
       $query->addSelect(['tag']); 
      } 
     ]) 
     ->where('tag', urldecode($passedTag)) 
     ->firstOrFail()->posts->toArray() 
    ]); 
} catch (ModelNotFoundException $e) { 
    return response()->json(['errors' => 'No query results for: '. $passedTag]); 
} 

急切加載意味着,您可以在對象被自動檢索時預加載任何對象的關係。這不僅會減少查詢負載,而且還會爲您提供所需的所有數據,而無需額外的循環或數據庫調用。正如你可以看到你可以窩預先加載,加載關係的關係 - posts.tags

編輯

這種急切關係的負荷會獲取你只能從相關的標籤的標籤欄:

'posts.tags' => function ($query) { 
    $query->addSelect(['tag']); 
} 
+0

謝謝,不知道你可以像這樣鏈接它。然而,當使用'firstOrFail()'我得到錯誤'致命錯誤:調用未定義的方法Illuminate \ Database \ Eloquent \ Collection :: addEagerConstraints()' – Musterknabe

+0

@Musterknabe嗯我在Laravel 5 atm測試它和它是完美的工作,但也許在流明有一個問題。給我一分鐘安裝Lumen並測試它。 – shaddy

+0

太棒了。謝謝。是的,也許這與LUmen – Musterknabe