Laravel Eloquent - 通过用户模型上的方法订购用户关系

时间:2017-07-25 10:07:18

标签: laravel laravel-5 eloquent

我正在使用Laravel Spark处理API端点。

此端点返回给定的团队及其用户。

// in App\Team

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

但是,我希望通过用户模型上的方法对这些用户进行排序。

在我的App \ User模型上,我有一个方法:

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

有什么方法可以返回用户关系,但是按照该方法的结果对用户进行排序?

2 个答案:

答案 0 :(得分: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()是一项代价高昂的操作(基于您的评论),所以理想情况下,这可能是您可以有条件地做的事情,但是,我&# 39;我不确定该怎么做!您可能需要重新考虑实施currentQueueLength()的方法,这可能会为您构建此查询的方式提供更多选项。

答案 1 :(得分:0)

您可以通过对用户进行排序来实现此目的:

ToString()

有关排序的更多信息:要按升序排序,请在第一项小于第二项时返回-1。所以你可以使用:

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

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

要按降序排序,请在第一项少于第二项时返回+1。

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

如果它是用户模型中的字段,您可以这样做:

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

对于财产的情况:

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

希望有所帮助:)