J'essaie d'obtenir les hackathons les plus populaires, qui nécessitent d'être commandés par la fonction partipants->count()
du hackathon respectif. Désolé si c'est un peu difficile à comprendre.
J'ai une base de données au format suivant:
hackathons
id
name
...
hackathon_user
hackathon_id
user_id
users
id
name
Le modèle Hackathon
est:
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');
}
}
Et HackathonParticipant
est défini comme:
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');
}
}
J'ai essayé Hackathon::orderBy(HackathonParticipant::find($this->id)->count(), 'DESC')->take(5)->get());
mais je sens que j'ai commis une grosse erreur (peut-être le $ this-> id), car cela ne fonctionne pas du tout.
Comment pourrais-je essayer d'obtenir les hackathons les plus populaires basés sur le plus grand nombre de hackathonParticipants associés?
Vous devriez pouvoir utiliser les méthodes sortBy()
et count()
de Collection
pour le faire assez facilement.
$hackathons = Hackathon::with('participants')->get()->sortBy(function($hackathon)
{
return $hackathon->participants->count();
});
Cela fonctionne pour moi dans Laravel 5.3, en utilisant votre exemple:
Hackathon::withCount('participants')->orderBy('participants_count', 'desc')->paginate(10);
De cette façon, il est ordonné sur la requête et la pagination fonctionne bien.
Une autre approche peut être d'utiliser la méthode withCount()
.
Hackathon::withCount('participants')
->orderBy('participants_count', 'desc')
->paginate(50);
Réf: https://laravel.com/docs/5.5/eloquent-relationships#querying-relations
J'avais un problème similaire et utiliser sortBy () n'est pas approprié à cause de la pagination, exactement comme Sabrina Gelbart l'a commenté dans la solution précédente .
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);
Vous pouvez également utiliser l'opérateur de jointure. Comme Sabrina l'a dit, vous ne pouvez pas utiliser Sortby au niveau de la base de données.
$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);
Mais ce code prend tous les enregistrements de la base de données. Donc, vous devriez paginer manuellement.
$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();
Référé de: https://stackoverflow.com/a/26384024/2186887