Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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.

like image 241
KeizerBridge Avatar asked Oct 24 '14 15:10

KeizerBridge


People also ask

How do I access pivot table data?

You can quickly enter a simple GETPIVOTDATA formula by typing = (the equal sign) in the cell you want to return the value to and then clicking the cell in the PivotTable that contains the data you want to return.

How does eloquent ORM work?

Eloquent is an object relational mapper (ORM) that is included by default within the Laravel framework. An ORM is software that facilitates handling database records by representing data as objects, working as a layer of abstraction on top of the database engine used to store an application's data.

What is pivot table in Laravel?

Definition of Laravel Pivot Table. A pivot table is defined as the set of values arranged in a table form where every distinct value of the concerned table can be accessed in the form of a spreadsheet, database, and so on. It is available in one or multiple discrete functionalities.


2 Answers

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.

like image 113
Jarek Tkaczyk Avatar answered Sep 21 '22 15:09

Jarek Tkaczyk


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.

like image 43
Sergiu Avatar answered Sep 18 '22 15:09

Sergiu