在我的数据库中,我有:
tops
表posts
表tops_has_posts
表。当我在tops
表格中检索到顶部时,我还会检索与顶部相关的posts
。
但是,如果我想按特定顺序检索这些帖子怎么办?
所以我在我的数据透视表range
中添加了一个tops_has_posts
字段,我尝试使用Eloquent按结果排序,但它不起作用。
我试试这个:
$top->articles()->whereHas('articles', function($q) {
$q->orderBy('range', 'ASC');
})->get()->toArray();
而且:
$top->articles()->orderBy('range', 'ASC')->get()->toArray();
两者都是绝望的尝试。
提前谢谢。
答案 0 :(得分:13)
如果您使用table.field
,有两种方法 - 一种使用指定pivot_field
,另一种使用Eloquent别名withPivot('field')
:
// if you use withPivot
public function articles()
{
return $this->belongsToMany('Article', 'tops_has_posts')->withPivot('range');
}
// then: (with not whereHas)
$top = Top::with(['articles' => function ($q) {
$q->orderBy('pivot_range', 'asc');
}])->first(); // or get() or whatever
这样可行,因为Eloquent将withPivot
中提供的所有字段别名为pivot_field_name
。
现在,通用解决方案:
$top = Top::with(['articles' => function ($q) {
$q->orderBy('tops_has_posts.range', 'asc');
}])->first(); // or get() or whatever
// or:
$top = Top::first();
$articles = $top->articles()->orderBy('tops_has_posts.range', 'asc')->get();
这将订购相关的查询。
注意:以这种方式命名,不要让你的生活变得艰难。 posts
不一定是articles
,我会使用其中一个或另一个名称,除非确实需要这个。
答案 1 :(得分:4)
在Laravel 5.6+(不确定旧版本)中使用它很方便:
public function articles()
{
return $this->belongsToMany('Article', 'tops_has_posts')->withPivot('range')->orderBy('tops_has_posts.range');
}
在这种情况下,只要您拨打articles
,他们就会被range
属性自动排序。
答案 2 :(得分:3)
如果打印出belongsToMany
关系的SQL查询,你会发现数据透视表的列名使用了pivot_
前缀作为新的别名。
例如,数据透视表中的 created_at
、updated_at
有 pivot_created_at
、pivot_updated_at
别名。所以 orderBy
方法应该使用这些别名。
这是一个如何做到这一点的例子。
class User {
...
public function posts(): BelongsToMany {
return $this->belongsToMany(
Post::class,
'post_user',
'user_id',
'post_id')
->withTimestamps()
->latest('pivot_created_at');
}
...
}
如果您愿意,可以使用 orderBy
代替 latest
方法。在上面的例子中,post_user
是数据透视表,你可以看到排序的列名现在是 pivot_created_at
或 pivot_updated_at
。
答案 3 :(得分:2)
在Laravel 5.4 中,我有以下关系在Set
模型belongsToMany
Job
模型中正常工作:
public function jobs()
{
return $this->belongsToMany(Job::class, 'eqtype_jobs')
->withPivot(['created_at','updated_at','id'])
->orderBy('pivot_created_at','desc');
}
上述关系会返回所有jobs
指定的set
已加入的数据透视表(eqtype_jobs)字段created_at
DESC。
$set->jobs()->paginate(20)
的SQL打印输出如下所示:
select `jobs`.*, `eqtype_jobs`.`set_id` as `pivot_set_id`,
`eqtype_jobs`.`job_id` as `pivot_job_id`,
`eqtype_jobs`.`created_at` as `pivot_created_at`,
`eqtype_jobs`.`updated_at` as `pivot_updated_at`,
`eqtype_jobs`.`id` as `pivot_id` from
`jobs` inner join `eqtype_jobs` on `jobs`.`id` = `eqtype_jobs`.`job_id` where
`eqtype_jobs`.`set_id` = 56
order by `pivot_created_at` desc limit 20 offset 0
答案 4 :(得分:1)
对于 Laravel 8.17.2 + ,您可以使用::orderByPivot()
。
答案 5 :(得分:0)
试试这个:
$top->articles()->orderBy('pivot_range','asc')->get();