LaravelEloquent:排序Many-to-Many查询-用户收藏优先

Laravel Eloquent: ordering Many-to-Many query- user favorites first


我的 Laravel 应用程序 return 是供用户管理的船舶列表。我想 return 由活跃用户 "favorited" 的船只先于其他船只。例如:

我在 UserShip 之间有一个 many-to-many 关系,其中 ship->userFavorite return 是拥有 "favorited" 飞船的用户.

我可以想象出 2 种解决方案,但我不确定它们是否可行以及如何实现它们。

  1. 一个orderby查询,根据收藏夹等于活跃用户进行排序

    $ships = Ship::orderby([ship->userfavorite being equal to Auth::User()], 'ASC')
    ->orderby('name', 'ASC')->get();
    
  2. 我目前的解决方案:我先使用 wherehas 查询 return 最喜欢的船只 ($favships),然后使用另一个查询 return 所有船只($ships)。对于此解决方案,我想从第二个查询中删除最喜欢的船只。但是我怎样才能优雅地从结果中删除这些船呢?

    $user = Auth::user();
    $favships = Ship::wherehas('userFavorite', function($q) use($user)
    {
        $q->where('id', $user->id);
    })->orderBy('name', 'ASC')->get();
    $ships = Ship::orderBy('name', 'ASC')->get();
    

如果能帮助我加深对这个问题的理解,我们将不胜感激!

你可以使用

$normalShips= $ships->diff($favships);

但我认为您可以将 2 个查询减少到 1 个查询:

//Ship.php
public function currentUserFavorite() {
     $this->userFavorite()->where('id', Auth::user()->id);
}


// get all ships
$ships = Ship::with('currentUserFavorite')->orderBy('name', 'ASC')->get();

// finally
$favships = $ships->where('currentUserFavorite.0.id', Auth::user()->id);
$normalShips = $ships->diff($favships);

// or do a loop 
foreach ($ships as $ship) {
    if ($ship->currentUserFavorite->count() > 0) {
      $favships[] = $ship;
    } else {
      $normalShips[] = $ship;
    }
}