如何在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 10:19:36  来源:igfitidea点击:

How to order by pivot table data in Laravel's Eloquent ORM

phpmysqllaraveleloquent

提问by KeizerBridge

In my Database, I have:

在我的数据库中,我有:

  • topsTable
  • postsTable
  • tops_has_postsTable.
  • tops桌子
  • posts桌子
  • tops_has_posts桌子。

When I retrieve a top on my topstable I also retrieve the postsin relation with the top. But what if I want to retrieve these posts in a certain order ? So I add a rangefield in my pivot table tops_has_postsand 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_fieldif 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 withPivotas 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. postsare 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 rangeproperty.

在这种情况下,无论何时您调用articles,它们都会按range属性自动排序。

回答by SaidbakR

In Laravel 5.4I have the following relation that works fine in Setmodel which belongsToManyof Jobmodel:

在Laravel 5.4我有以下关系,在正常工作Set模式其中belongsToManyJob模型:

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 jobsthat the specified sethas been joined ordered by the pivot table's (eqtype_jobs) field created_atDESC.

上面的关系返回所有jobs指定的set已连接的数据透视表的 (eqtype_jobs) 字段created_atDESC。

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();