Laravel 订购的关系

我在循环一个特定的文章的作者发表的所有评论。

foreach($post->user->comments as $comment)
{
echo "<li>" . $comment->title . " (" . $comment->post->id . ")</li>";
}

这给了我

I love this post (3)
This is a comment (5)
This is the second Comment (3)

如何通过 post _ id 进行排序,使上面的列表按3、3、5进行排序

268165 次浏览

可以用查询函数扩展关系:

<?php
public function comments()
{
return $this->hasMany('Comment')->orderBy('column');
}

[编辑后评论]

<?php
class User
{
public function comments()
{
return $this->hasMany('Comment');
}
}


class Controller
{
public function index()
{
$column = Input::get('orderBy', 'defaultColumn');
$comments = User::find(1)->comments()->orderBy($column)->get();


// use $comments in the template
}
}

Default User model + simple Controller 示例; 当获取注释列表时,只需根据 Input: : get ()应用 orderBy ()。 (一定要做一些输入检查;)

我相信你也可以做到:

$sortDirection = 'desc';


$user->with(['comments' => function ($query) use ($sortDirection) {
$query->orderBy('column', $sortDirection);
}]);

这允许你在每个相关的评论记录上运行任意的逻辑,你可以在那里有这样的东西:

$query->where('timestamp', '<', $someTime)->orderBy('timestamp', $sortDirection);

使用 sortBy...会有所帮助。

$users = User::all()->with('rated')->get()->sortByDesc('rated.rating');

试试这个方法。

$mainModelData = mainModel::where('column', $value)
->join('relationModal', 'main_table_name.relation_table_column', '=', 'relation_table.id')
->orderBy('relation_table.title', 'ASC')
->with(['relationModal' => function ($q) {
$q->where('column', 'value');
}])->get();

例如:

$user = User::where('city', 'kullu')
->join('salaries', 'users.id', '=', 'salaries.user_id')
->orderBy('salaries.amount', 'ASC')
->with(['salaries' => function ($q) {
$q->where('amount', '>', '500000');
}])->get();

可以根据数据库结构更改 join()中的列名。

我在关系域上做了一个按顺序排列的特征。我有这个问题与网店订单有一个状态关系,和状态有一个名称字段。

情况的一个例子

用雄辩的模型的“连接”进行排序是不可能的,因为它们不是连接。它们是在第一个查询完成后运行的查询。因此,我所做的就是编写一个 lil hack 来读取有说服力的关系数据(比如表、连接键和其他包含在内的位置) ,并将其连接到主查询上。这只适用于一对一的关系。

第一步是创建一个 trait 并在模型上使用它。在这个特性中,你有两个功能。第一个:

/**
* @param string $relation - The relation to create the query for
* @param string|null $overwrite_table - In case if you want to overwrite the table (join as)
* @return Builder
*/
public static function RelationToJoin(string $relation, $overwrite_table = false) {
$instance = (new self());
if(!method_exists($instance, $relation))
throw new \Error('Method ' . $relation . ' does not exists on class ' . self::class);
$relationData = $instance->{$relation}();
if(gettype($relationData) !== 'object')
throw new \Error('Method ' . $relation . ' is not a relation of class ' . self::class);
if(!is_subclass_of(get_class($relationData), Relation::class))
throw new \Error('Method ' . $relation . ' is not a relation of class ' . self::class);
$related = $relationData->getRelated();
$me = new self();
$query = $relationData->getQuery()->getQuery();
switch(get_class($relationData)) {
case HasOne::class:
$keys = [
'foreign' => $relationData->getForeignKeyName(),
'local' => $relationData->getLocalKeyName()
];
break;
case BelongsTo::class:
$keys = [
'foreign' => $relationData->getOwnerKeyName(),
'local' => $relationData->getForeignKeyName()
];
break;
default:
throw new \Error('Relation join only works with one to one relationships');
}
$checks = [];
$other_table = ($overwrite_table ? $overwrite_table : $related->getTable());
foreach($keys as $key) {
array_push($checks, $key);
array_push($checks, $related->getTable() . '.' . $key);
}
foreach($query->wheres as $key => $where)
if(in_array($where['type'], ['Null', 'NotNull']) && in_array($where['column'], $checks))
unset($query->wheres[$key]);
$query = $query->whereRaw('`' . $other_table . '`.`' . $keys['foreign'] . '` = `' . $me->getTable() . '`.`' . $keys['local'] . '`');
return (object) [
'query' => $query,
'table' => $related->getTable(),
'wheres' => $query->wheres,
'bindings' => $query->bindings
];
}

这是读取雄辩数据的“检测”函数。

第二个:

/**
* @param Builder $builder
* @param string $relation - The relation to join
*/
public function scopeJoinRelation(Builder $query, string $relation) {
$join_query = self::RelationToJoin($relation, $relation);
$query->join($join_query->table . ' AS ' . $relation, function(JoinClause $builder) use($join_query) {
return $builder->mergeWheres($join_query->wheres, $join_query->bindings);
});
return $query;
}

这个函数将范围添加到模型中,以便在查询的。现在只要在你的模型上使用 trait,你可以这样使用它:

Order::joinRelation('status')->select([
'orders.*',
'status.name AS status_name'
])->orderBy('status_name')->get();