Open sidebar
/****************************************** The Base Model ******************************************/ <?php namespace App; use Illuminate\Support\Facades\DB; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Query\Builder; class BaseModel extends Model { /** * query scope nPerGroup * * @return void */ public function scopeNPerGroup($query, $group, $n = 10) { // queried table $table = ($this->getTable()); // initialize MySQL variables inline $query->from( DB::raw("(SELECT @rank:=0, @group:=0) as vars, {$table}") ); // if no columns already selected, let's select * if ( ! $query->getQuery()->columns) { $query->select("{$table}.*"); } // make sure column aliases are unique $groupAlias = 'group_'.md5(time()); $rankAlias = 'rank_'.md5(time()); // apply mysql variables $query->addSelect(DB::raw( "@rank := IF(@group = {$group}, @rank+1, 1) as {$rankAlias}, @group := {$group} as {$groupAlias}" )); // make sure first order clause is the group order $query->getQuery()->orders = (array) $query->getQuery()->orders; array_unshift($query->getQuery()->orders, ['column' => $group, 'direction' => 'asc']); // prepare subquery $subQuery = $query->toSql(); // prepare new main base Query\Builder $newBase = $this->newQuery() ->from(DB::raw("({$subQuery}) as {$table}")) ->mergeBindings($query->getQuery()) ->where($rankAlias, '<=', $n) ->getQuery(); // replace underlying builder to get rid of previous clauses $query->setQuery($newBase); } } /*********************************************************** The Board Model extending it ***********************************************************/ <?php namespace App; use App\BaseModel; class Board extends BaseModel { public function pins() { return $this->hasMany('App\Pin'); } public function recentPins() { return $this->pins()->latest()->nPerGroup('board_id', 5); } } /*********************************************************** Calling the method in Tinker ***********************************************************/ App\Board::with('latestComments')->get();
Close sidebar
Back
Please note that all pasted data is publicly available.
X (fomerly Twitter)
GitHub
Use setting
Back
Please note that all pasted data is publicly available.
X (fomerly Twitter)
GitHub
Use setting