如何在 Laravel 的 Eloquent ORM 中按数据透视表数据排序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26551078/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to order by pivot table data in Laravel's Eloquent ORM
提问by KeizerBridge
In my Database, I have:
在我的数据库中,我有:
tops
Tableposts
Tabletops_has_posts
Table.
tops
桌子posts
桌子tops_has_posts
桌子。
When I retrieve a top on my tops
table I also retrieve the posts
in relation with the top.
But what if I want to retrieve these posts in a certain order ?
So I add a range
field in my pivot table tops_has_posts
and I my trying to order by the result using Eloquent but it doesn't work.
当我在我的tops
桌子上检索一个顶部时,我也会检索posts
与顶部相关的 。但是如果我想按特定顺序检索这些帖子怎么办?因此,我range
在数据透视表中添加了一个字段,tops_has_posts
并尝试使用 Eloquent 按结果排序,但它不起作用。
I try this :
我试试这个:
$top->articles()->whereHas('articles', function($q) {
$q->orderBy('range', 'ASC');
})->get()->toArray();
And this :
和这个 :
$top->articles()->orderBy('range', 'ASC')->get()->toArray();
Both were desperate attempts.
两者都是绝望的尝试。
Thank you in advance.
先感谢您。
回答by Jarek Tkaczyk
There are 2 ways - one with specifying the table.field
, other using Eloquent alias pivot_field
if you use withPivot('field')
:
有两种方法 - 一种是指定table.field
,另一种使用 Eloquent 别名,pivot_field
如果你使用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
This will work, because Eloquent aliases all fields provided in withPivot
as pivot_field_name
.
这会起作用,因为 Eloquent 将所有字段别名withPivot
为 as pivot_field_name
。
Now, generic solution:
现在,通用解决方案:
$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();
This will order the related query.
这将对相关查询进行排序。
Note:Don't make your life hard with naming things this way. posts
are not necessarily articles
, I would use either one or the other name, unless there is really need for this.
注意:不要以这种方式命名事物,这会让您的生活变得艰难。posts
不一定articles
,我会使用一个或另一个名称,除非确实需要这样做。
回答by Sergiu
In Laravel 5.6+ (not sure about older versions) it's convenient to use this:
在 Laravel 5.6+(不确定旧版本)中,使用这个很方便:
public function articles()
{
return $this->belongsToMany('Article', 'tops_has_posts')->withPivot('range')->orderBy('tops_has_posts.range');
}
In this case, whenever you will call articles
, they will be sorted automaticaly by range
property.
在这种情况下,无论何时您调用articles
,它们都会按range
属性自动排序。
回答by SaidbakR
In Laravel 5.4I have the following relation that works fine in Set
model which belongsToMany
of Job
model:
在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');
}
The above relation returns all jobs
that the specified set
has been joined ordered by the pivot table's (eqtype_jobs) field created_at
DESC.
上面的关系返回所有jobs
指定的set
已连接的数据透视表的 (eqtype_jobs) 字段created_at
DESC。
The SQL printout of $set->jobs()->paginate(20)
Looks like the following:
的 SQL 打印输出$set->jobs()->paginate(20)
如下所示:
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
回答by hamidteimouri
in your blade try this:
在你的刀片中试试这个:
$top->articles()->orderBy('pivot_range','asc')->get();