私は、それぞれのハッカソンのpartipants->count()
による注文を必要とする最も人気のあるハッカソンを取得しようとしています。理解するのが少し難しい場合は申し訳ありません。
次の形式のデータベースがあります。
_hackathons
id
name
...
hackathon_user
hackathon_id
user_id
users
id
name
_
Hackathon
モデルは次のとおりです。
_class Hackathon extends \Eloquent {
protected $fillable = ['name', 'begins', 'ends', 'description'];
protected $table = 'hackathons';
public function owner()
{
return $this->belongsToMany('User', 'hackathon_owner');
}
public function participants()
{
return $this->belongsToMany('User');
}
public function type()
{
return $this->belongsToMany('Type');
}
}
_
HackathonParticipant
は次のように定義されます:
_class HackathonParticipant extends \Eloquent {
protected $fillable = ['hackathon_id', 'user_id'];
protected $table = 'hackathon_user';
public function user()
{
return $this->belongsTo('User', 'user_id');
}
public function hackathon()
{
return $this->belongsTo('Hackathon', 'hackathon_id');
}
}
_
Hackathon::orderBy(HackathonParticipant::find($this->id)->count(), 'DESC')->take(5)->get());
を試しましたが、まったく機能しないため、大きな間違い(おそらく$ this-> id)を犯したように感じます。
関連するハッカソン参加者の最大数に基づいた最も人気のあるハッカソンを取得しようとするにはどうすればよいですか?
Collection
のsortBy()
およびcount()
メソッドを使用して、これをかなり簡単に行うことができるはずです。
$hackathons = Hackathon::with('participants')->get()->sortBy(function($hackathon)
{
return $hackathon->participants->count();
});
これはLaravel 5.3であなたの例を使って動作します:
Hackathon::withCount('participants')->orderBy('participants_count', 'desc')->paginate(10);
このように、クエリで順序付けされ、ページネーションがうまく機能します。
別のアプローチは、withCount()
メソッドを使用することです。
Hackathon::withCount('participants')
->orderBy('participants_count', 'desc')
->paginate(50);
参照: https://laravel.com/docs/5.5/eloquent-relationships#querying-relations
Sabrina Gelbartが以前のソリューションでコメントしたとおり、ページネーションが原因でsortBy()を使用するのは適切ではありません。そこで、db rawを使用しました。ここでは簡単なクエリを示します。
Tag::select(
array(
'*',
DB::raw('(SELECT count(*) FROM link_tag WHERE tag_id = id) as count_links'))
)->with('links')->orderBy('count_links','desc')->paginate(5);
結合演算子を使用することもできます。 Sabrinaが言ったように、dbレベルでsortbyを使用することはできません。
$hackathons = Hackathon::leftJoin('hackathon_user','hackathon.id','=','hackathon_user.hackathon_id')
->selectRaw('hackathon.*, count(hackathon_user.hackathon_id) AS `count`')
->groupBy('hackathon.id')
->orderBy('count','DESC')
->paginate(5);
ただし、このコードはデータベースからすべてのレコードを取得します。したがって、手動でページ分割する必要があります。
$hackathons = Hackathon::leftJoin('hackathon_user','hackathon.id','=','hackathon_user.hackathon_id')
->selectRaw('hackathon.*, count(hackathon_user.hackathon_id) AS `count`')
->groupBy('hackathon.id')
->orderBy('count','DESC')
->skip(0)->take(5)->get();