Skip to content

Instantly share code, notes, and snippets.

@smgladkovskiy
Last active August 29, 2015 14:08
Show Gist options
  • Save smgladkovskiy/6dc95dea938e2b26036a to your computer and use it in GitHub Desktop.
Save smgladkovskiy/6dc95dea938e2b26036a to your computer and use it in GitHub Desktop.
Laravel 4 Relation table column orderBy scope
<?php namespace Site\Traits;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Builder;
trait RelationOrderScopeTrait {
/**
* Order also and by related table column
*
* $orderByData = ['relation.columnName' , 'asc'];
*
* @param Builder $builder
* @param array $orderByArray
* @return Builder
*/
public function scopeSmartOrderBy($builder, array $orderByArray)
{
$model = $builder->getModel();
list($orderColumn, $orderDirection) = $orderByArray;
$this->assignArrayByPath($orderByData, $orderColumn, $orderDirection);
foreach ($orderByData as $sort => $order)
{
if (is_array($order))
{
foreach ($order as $column => $value)
{
$relation = $model->{$sort}();
if ($relation instanceof BelongsTo or $relation instanceof HasOne)
{
return $builder->join(
$relation->getRelated()->getTable().' as '.$sort,
$sort.'.'.$relation->getOtherKey(),
'=',
$relation->getForeignKey()
)
->orderBy($sort.'.'.$column, $value)
// select model.* to be able to retrieve properties well
->select($model->getTable().'.*');
}
}
}
return $builder->orderBy($model->getTable().'.'.$sort, $order);
}
return $builder;
}
/**
* @param array $arr
* @param string $path
* @param mixed $value
*
* @return void
*/
private function assignArrayByPath(&$arr, $path, $value)
{
$keys = explode('.', $path);
while ($key = array_shift($keys)) {
$arr = &$arr[$key];
}
$arr = $value;
}
}
@divdax
Copy link

divdax commented Aug 11, 2015

Laravel 4.2
Try to use this, but got "method does not exist":

$relation->getOtherKey()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment