-
-
Save jhaoda/d757c39aaba97b754b1dcaa10366cb2f to your computer and use it in GitHub Desktop.
Additional helper scopes for Laravel Eloquent Models: `->orderByRelation('author', 'name')`; `->orderByRelationCount('posts')`; `->withJoinnedRelated('author', 'name')`;
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App; | |
use Illuminate\Database\Eloquent\Builder; | |
use Illuminate\Database\Eloquent\Model; | |
use Illuminate\Database\Query\Builder as QueryBuilder; | |
use Illuminate\Database\Query\Expression; | |
abstract class BaseModel extends Model | |
{ | |
/** | |
* Сортировка выборки по полю из связанной модели. | |
* | |
* :WARNING: only for hasOne relation. | |
* :FIXME: check query->column before reset select. | |
* | |
* @param Builder|QueryBuilder $query | |
* @param string $relation | |
* @param string|string[] $column | |
* @param string $direction | |
* @return Builder|QueryBuilder | |
*/ | |
public function scopeOrderByRelation($query, $relation, $column, $direction = 'asc') | |
{ | |
if (null === $query->getQuery()->columns) { | |
$query->select([$this->getTable() . '.*']); | |
} | |
$relation = $query->getRelation($relation); | |
$related_table = $relation->getRelated()->getTable(); | |
//for laravel "< 5.4" | |
//$query->leftJoin($related_table, $relation->getForeignKey(), '=', $relation->getQualifiedParentKeyName()); | |
$query->leftJoin($related_table, $relation->getQualifiedForeignKeyName(), '=', $relation->getQualifiedParentKeyName()); | |
foreach ((array) $column as $order) { | |
$query->orderBy($related_table . '.' . $order, $direction); | |
} | |
return $query; | |
} | |
/** | |
* Сортировка выборки по кол-ву связанных записей. | |
* | |
* :INFO: для связей hasMany и belongsToMany | |
* | |
* @param Builder|QueryBuilder $query | |
* @param string $relation | |
* @param string $direction | |
* @return Builder|QueryBuilder | |
*/ | |
public function scopeOrderByRelationCount($query, $relation, $direction = 'asc') | |
{ | |
return $query->withCount($relation)->orderBy(snake_case($relation) . '_count', $direction); | |
} | |
/** | |
* Выборка полей из связанной модели с помощью джоина. | |
* | |
* :WARNING: only for hasOne relation. | |
* | |
* @param Builder|QueryBuilder $query | |
* @param string $relation | |
* @param array|string $column | |
* @return Builder|QueryBuilder | |
*/ | |
public function scopeWithJoinedRelated($query, $relation, $column) | |
{ | |
if (null === $query->getQuery()->columns) { | |
$query->select([$this->getTable() . '.*']); | |
} | |
$relation_name = snake_case($relation); | |
$relation = $query->getRelation($relation); | |
$related_table = $relation->getRelated()->getTable(); | |
//for laravel "< 5.4" | |
//$query->leftJoin($related_table, $relation->getForeignKey(), '=', $relation->getQualifiedParentKeyName()); | |
$query->leftJoin($related_table, $relation->getQualifiedForeignKeyName(), '=', $relation->getQualifiedParentKeyName()); | |
foreach ((array) $column as $name) { | |
$segments = explode(' ', $name); | |
$alias = "{$relation_name}_{$name}"; | |
if (count($segments) === 3 && Str::lower($segments[1]) === 'as') { | |
list($name, $alias) = [$segments[0], $segments[2]]; | |
} | |
$query->addSelect("{$related_table}.{$name} as {$alias}"); | |
} | |
return $query; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment