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

前端 未结 5 680
难免孤独
难免孤独 2020-12-17 11:11

In my Database, I have:

  • tops Table
  • posts Table
  • tops_has_posts Table.

When I retrieve a

相关标签:
5条回答
  • 2020-12-17 11:12

    in your blade try this:

    $top->articles()->orderBy('pivot_range','asc')->get();
    
    0 讨论(0)
  • 2020-12-17 11:13

    For Laravel 8.17.2+ you can use ::orderByPivot().

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

    0 讨论(0)
  • 2020-12-17 11:15

    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
    
    0 讨论(0)
  • 2020-12-17 11:23

    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.

    0 讨论(0)
  • 2020-12-17 11:30

    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.

    0 讨论(0)
提交回复
热议问题