Ad

How To Stop Auto Sorting In Laravel Pivot Table Of Many To Many Realtion

- 1 answer

I have a author table and a publication table. Both are related to each other in a many to many relation. When I'm inserting the publications the authors of the publications are inserted in the pivot table by the order of authors id. But I need to insert it by the order i'm selecting the authors in the front-end. Whatever the order of the authors in the front end is it is getting ordered by the author's id in the pivot table. How can i stop this automatic ordering

Ad

Answer

You can't add rows in a specific order into a pivot table, because it doesn't really make sense.

Let's consider an users table:

  1. The first user you enter will have the id 1
  2. The second will be assigned to the id 2
  3. And so on...

So you can enter the users in a specific order and retrieve them by their id.

However, in a standard pivot table, the primary key is composed by two columns, in your case the author_id and publication_id. Nothing new is created here, you just associate the primary key of two existing rows in two differents tables in order to achieve one - and unique - composed primary key.

If i explained well (and i hope so :p), you should understand why saying

But I need to insert it by the order i'm selecting the authors in the front-end.

doesn't really make sense.

But, don't worry, it is still possible to achieve your goal here.

Instead of using a pivot table, you can use a normal table with an id. This way, the order of insertion will be preserved. It will work but that's not very nice.

A better approach would be to add an additional column to the pivot table. A column like position. This column could be incremented for each author you insert. Then, you can order the table by the position column, by simply adding ->orderBy('position') to your relationship or every queries that needs to.

Here is an example to illustrate what i said above:

foreach($authors as $position => $author)
{
    $publication->authors()->attach($author, ['position' => $position]);
}

If $authors contains the authors in the order you selected them on the front-end, they will be added accordingly.

If you need to sync instead of attach, that's also possible, it's just a little bit more verbose:

$syncData = $authors->mapWithKeys(function($author, $position){
    return [$author->id => ['position' => $position]];
});

$publication->authors()->sync($syncData);

Don't forget that you can add false as a second parameter on the sync method so it'll only add new authors.

After that, just change your authors relationship in your Publication model like this:

public function authors(){
    return $this->belongsToMany(Author::class)->orderBy('position');
}

Or everywhere you need to:

$publication->authors()->orderBy('position')->get();

I hope it helps !

Ad
source: stackoverflow.com
Ad