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

别说谁变了你拦得住时间么 提交于 2019-12-22 03:17:10

问题


In my Database, I have:

  • tops Table
  • posts Table
  • tops_has_posts Table.

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.

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.


回答1:


There are 2 ways - one with specifying the table.field, other using Eloquent alias pivot_field if you use 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.

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.




回答2:


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');
}

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




回答3:


In Laravel 5.4 I have the following relation that works fine in Set model which belongsToMany of Job model:

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.

The SQL printout of $set->jobs()->paginate(20) Looks like the following:

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:


in your blade try this:

$top->articles()->orderBy('pivot_range','asc')->get();


来源:https://stackoverflow.com/questions/26551078/how-to-order-by-pivot-table-data-in-laravels-eloquent-orm

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!