2017-07-25 73 views
0

我正在使用Laravel Spark開發API端點。Laravel Eloquent - 通過用戶模型中的方法來訂購用戶關係

此端點將給定團隊及其用戶返回。

// in App\Team 

public function users() 
{ 
    return $this->belongsToMany(
     'App\User', 'team_users', 'team_id', 'user_id' 
    )->withPivot('role'); 
} 

但是,我希望通過在用戶模型上的方法來訂購這些用戶。

我的應用程序\ User模型我有一個方法:

public function currentQueueLength() 
{ 
    returns an integer based upon the users current appointments, 
} 

有什麼辦法,我可以返回用戶的關係,但通過該方法的結果訂購的用戶?

+0

「User :: currentQueueLength()」做了什麼? – haakym

+1

@haakym運行一個可怕的循環來計算用戶服務的總時間。用戶是一名理髮師,可以有許多指定服務的約會。有各種模型關係,但該方法返回整數分鐘。通常稱爲例如$ user-> currentQueueLength() – Lovelock

+0

陷阱。我的第一個想法是,你可以使用'$ appends'屬性和一個訪問器方法來預加載'currentQueueLength()'作爲'User'模型的一個屬性,然後通過'Team :: users() '電話。這種方法的問題在於,它聽起來像'currentQueueLength()'是一個代價高昂的操作(基於你的最後一條評論,是嗎?),所以理想情況下,這是你可以有條件地做的事情。也許重構你的'currentQueueLength()'可能是第一步? – haakym

回答

0

您可以通過排序的用戶這樣acheave這樣的:大約排序

Team::with('users') 
    ->all(); 

$team->users->sort(
    function ($user1, $user2) { 
     return $user1->currentQueueLength() - $user2->currentQueueLength(); 
    } 
); 

更多信息:要以升序排序,返回-1時,第一項小於第二項。因此您可以使用:

return $user1->currentQueueLength() < $user2->currentQueueLength() ? -1 : 1; 

並按降序排序,當第一個項目小於第二個項目時返回+1。

return $user1->currentQueueLength() < $user2->currentQueueLength() ? 1 : -1; 

如果它在用戶模型中的字段,你可以做這樣的:

$teams = Team::with(['users' => function ($q) { 
    $q->orderBy('Field', 'asc'); // or desc 
}])->all(); 

對於財產的情況下:

// asc 
$team->users->sortBy('userProperty'); 
// desc 
$team->users->sortByDesc('userProperty'); 

希望幫助:)

+0

我認爲@lovelock想要在* Team :: users()調用中實現排序* 'currentQueueLength'目前也不是'User'的一個屬性,但它可能會成爲''appends' +訪問器的一個屬性,正如我在這個問題的評論中提到的那樣,但它可能是一個代價高昂的操作,不理想? – haakym

1

如果您將current_queue_length作爲屬性添加到User模型,則可以通過此命令屬性。

您可以將它添加到$appends陣列並創建一個訪問添加屬性:

class User extends Model { 

    protected $appends = ['currentQueueLength']; 

    public function getCurrentQueueLengthAttribute() 
    { 
     return $this->currentQueueLength(); 
    } 
} 

感謝這樣一個問題:Add a custom attribute to a Laravel/Eloquent model on load?

然後在Team你可以添加方法如下所示:

class Team extends Model { 

    public function users() 
    { 
     return $this->belongsToMany(
      'App\User', 'team_users', 'team_id', 'user_id' 
     )->withPivot('role'); 
    } 

    public function usersByCurrentQueueLength() 
    { 
     return $this->users->orderBy('current_queue_length'); 
    } 

} 

正如我在評論中提到的那樣,這種方法的問題是,它聽起來像是currentQueueLength()是一個代價高昂的操作(基於你的評論),所以理想情況下,這將是你可以有條件地做的事情,但是,我不確定如何做到這一點!您可能需要重新考慮實施currentQueueLength()的方法,這可能會爲構建此查詢的方式提供更多選項。