如何在Laravel的Eloquent ORM中通过数据透视表数据进行排序

Kei*_*dge 10 php mysql laravel eloquent

在我的数据库中,我有:

  • tops
  • posts
  • tops_has_posts 表.

当我在tops桌子上检索顶部时,我还检索了posts与顶部有关的内容.但是,如果我想按特定顺序检索这些帖子怎么办?所以我range在我的数据透视表中添加一个字段,我tops_has_posts尝试使用Eloquent按结果排序,但它不起作用.

我试试这个:

$top->articles()->whereHas('articles', function($q) {
    $q->orderBy('range', 'ASC');
})->get()->toArray();
Run Code Online (Sandbox Code Playgroud)

还有这个 :

$top->articles()->orderBy('range', 'ASC')->get()->toArray();
Run Code Online (Sandbox Code Playgroud)

两人都是绝望的尝试.

先感谢您.

Jar*_*zyk 15

有两种方法 - 一种是指定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
Run Code Online (Sandbox Code Playgroud)

这将起作用,因为Eloquent别名withPivot为as中提供的所有字段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();
Run Code Online (Sandbox Code Playgroud)

这将订购相关的查询.

注意:不要以这种方式命名.posts不一定articles,我会使用其中一个或另一个名称,除非确实需要这个.


Jak*_*mec 7

对于Laravel 8.17.2+,您可以使用::orderByPivot().

https://github.com/laravel/framework/releases/tag/v8.17.2

  • 谢谢提示,不幸的是它还没有出现在文档中...... (2认同)
  • 哈哈,你是冠军!L9 的文档中仍然没有这个:https://github.com/laravel/docs/search?q=orderByPivot (2认同)

Ser*_*giu 5

In Laravel 5.6+ (not sure about older versions) it's convenient to use this:

public function articles()
{
  return $this->belongsToMany('Article', 'tops_has_posts')->withPivot('range')->orderBy('tops_has_posts.range');
}
Run Code Online (Sandbox Code Playgroud)

In this case, whenever you will call articles, they will be sorted automaticaly by range property.


Sai*_*akR 5

在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');
    }
Run Code Online (Sandbox Code Playgroud)

上面的关系返回所有已由数据透视表的(eqtype_jobs)字段DESC 排序jobs的指定set连接created_at

的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
Run Code Online (Sandbox Code Playgroud)

  • 这 ->orderBy('pivot_created_at','desc'); 为我工作。多谢。 (2认同)