好吧,你試圖讓一個用戶,但與他們的球員(其中用戶bTM球員)已經填充和按位置(其中樞軸bT位置)排序。
在這種情況下,您將無法不經修改就使用Laravel的內置關係方法,因爲Laravel並非專門用於處理其他關係數據透視表上的關係。幸運的是,ORM具有足夠的靈活性,可以讓您通過「手動」連接完成所需的任務。
那麼直接回答你的問題,這裏的代碼,你需要的那種(你非常接近!):
$user = User::with(['players' => function ($q) {
$q->join('position', 'league_player_user.position_id', '=', 'position.id')
->orderBy('position.sort_id', 'asc');
}])->where('id', Auth::user()->id)->first();
然而,在我看來,這不是偉大的代碼有以下幾個原因:
- 你手工獲得授權的用戶(當
Auth::user()
是所以方便)
- 你實際上是不得不採取的具體實現邏輯從日(事實上,數據透視表被稱爲
league_player_user
,並把它...以及無論這是哪裏(您的控制器?)
- 這隻會影響這一個單一的查詢 - 如果你碰巧得到
User
某種其他方式(例如Auth::user()
或User::find(1)
或其他),你不會有玩家正確
有序因此,我可能會建議,讓你的查詢更加簡單的目的,你不要急於負載的球員。因此,所有你需要做的前期是:
$user = Auth::user();
現在,(在你的User
類球員()方法)的關係,你做的特殊訂貨工作:
public function players()
{
return $this->belongsToMany('App\Models\Player', 'league_player_user')
->withPivot('position_id')
->join('position', 'league_player_user.position_id', '=', 'position.id')
->orderBy('position.sort_id');
}
這樣,任何時候你打電話$user->players
,你會得到他們正確的順序。
我必須補充一點,這樣做可能不會讓你急於加載玩家,因爲Laravel急於加載(即在ORM鏈中使用->with()
),這是由於Laravel執行急切的加載查詢的方式 - 一個用於主要查詢(即用戶)和一個關係(即玩家),但它執行此查詢以獲取所有結果,因此可能無法與特殊訂購系統配合使用。你將不得不看看你是否真的在意急於加載玩家。在上面的例子中(你得到的是單個授權用戶),我認爲急切的加載並不重要。
編輯補充關於預先加載澄清:
我的背後暗示預先加載可能不工作的理由是,在Laravel渴望加載還挺喜歡這樣做:說你有類別和產品:Category
HM Product
,Product
bT Category
。要獲得您使用的類別$category = Category::find(1)
,並且Laravel將其轉換爲查詢,如下所示:SELECT * FROM `categories` WHERE `id` = '1'
。如果您隨後致電$category->products
,Laravel將發出SELECT * FROM `products` WHERE `category_id` = '1'
。這很明智。但是,如果你有下面的代碼它會更糟糕:
<?php $categories = Category::all(); ?>
<ul>
@foreach ($categories as $category)
<li>Category {{{ $category->name }}} contains {{{ $category->products->count() }}} products.</li>
@endforeach
</ul>
在這種情況下,你有以下疑問:
SELECT * FROM `categories`;
SELECT * FROM `products` WHERE `category_id` = '1';
SELECT * FROM `products` WHERE `category_id` = '2';
SELECT * FROM `products` WHERE `category_id` = '3';
... as many categories as you had
但是,如果你要改變的是第一線,這:
<?php $categories = Category::with('products')->get(); ?>
現在你只有兩個疑問:
SELECT * FROM `categories`;
SELECT * FROM `products` WHERE `category_id` IN ('1', '2', '3', ...);
然後,Laravel在調用第二個查詢之後,將根據它知道的類別ID爲您創建各種集合。
但是,這是簡單化的關係案例。在你的情況下,products()
方法不僅僅是return $this->hasMany('Product');
,但它包括一個數據透視表和一個手動連接等等,而且第二個查詢,即急切加載的查詢,可能無法應付並且做到這一點正確排序。
正如我所說,我不確定這是如何工作的,這對我來說只是一個紅旗。通過一切手段給它一個去看看你得到了什麼 - 你可能會發現它適合你。
'User'模型中的'belongsToMany'會自動加入數據透視表(和遠表('players')),但不會加入'position'表(即使你說你想要position_id因此,你需要確保你自己添加額外的連接,我認爲你可以通過'User :: with('players','players.position')'做到這一點(儘管'position_id'是一個虛擬的你可能無法做到這一點,你必須使用代碼),重點在於'position'不會自動加入,所以你不能在它上面訂購。 – alexrussell
感謝@alexrussell。我已經看過這個,是的 - 也渴望加載嵌套關係。然後我可以在players.position中使用orderBy()查詢,儘管它沒有錯誤,但它並沒有正確地對結果進行排序。 – Alex
而不是使用' - > first()'use' - > toSql )'返回它正在生成的SQL - 這將幫助您準確調試ORM將要發佈的內容。 – alexrussell