Подтвердить что ты не робот

Счетчик отношений Laravel OrderBy

Я пытаюсь получить самые популярные хакафоны, которые требуют упорядочения по соответствующему hackathon 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), потому что он вообще не работает.

Как я могу попытаться получить самые популярные хакатоны, которые основаны на наибольшем числе связанных участников hackathonParticipants?

4b9b3361

Ответ 1

Изменение: Если вы используете Laravel 5.2 или выше, используйте kJamesy answer. Вероятно, он будет работать немного лучше, потому что не нужно будет загружать в память всех участников и хакатоны, только разбитые на страницы хакатоны и количество участников для этих хакатонов.

Вы должны быть в состоянии использовать методы Collection sortBy() и count(), чтобы сделать это довольно легко.

$hackathons = Hackathon::with('participants')->get()->sortBy(function($hackathon)
{
    return $hackathon->participants->count();
});

Ответ 2

Это работает для меня в Laravel 5.3, используя ваш пример:

Hackathon::withCount('participants')->orderBy('participants_count', 'desc')->paginate(10); 

Таким образом, он упорядочен по запросу, а разбиение на страницы работает красиво.

Ответ 4

У меня была аналогичная проблема, и использование 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);   

Ответ 5

Вы также можете использовать оператор объединения. Как сказала Сабрина, вы не можете использовать sortby на уровне db.

$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();

Рефералы: fooobar.com/info/311137/...