cdcdcd
cdcdcd

Reputation: 1722

Sorting a belongsToMany relationship by an array of ids

I have a model Classroom with a belongsToMany relationship. I want the order of its children to be eagerly determined by the array of ids already on the model e.g. student_ids has [5,1,7,9,2].

In other words, whenever I get a Classroom it should always pick its Students in that order.

public function students()
{
    return $this->belongsToMany(Student::class)->withTimestamps();
}

I've tried sortBy('student_ids') and orderBy('student_ids') which don't work — but I have managed to sort them by using something like this in my Classroom controller:

public function sortedStudents($ids)
{
    return $this->students()->sortBy(function ($student) use ($ids) {
        return array_search($student->id, $ids);
    });
}

This works but I need to pass in the ids after the fact. I would love to have it processed "by default" in the relationship itself.

Thanks. 🙂

Upvotes: 1

Views: 1186

Answers (2)

TsaiKoga
TsaiKoga

Reputation: 13394

you can use orderByRaw and FIELD() method to order by specific values sequence:

public function students()
{
    return $this->belongsToMany(Student::class)->withTimestamps()->orderByRaw("FIELD(id, 5,1,7,9,2)");
}

Upvotes: 2

Brian Lee
Brian Lee

Reputation: 18187

You can use the withPivot method to include the student ids which then allow ordering:

public function students()
{
    return $this->belongsToMany(Student::class)->withPivot('student_id')->orderBy('classroom_student.student_id');
}

I assumed in this example your pivot table is named classroom_student.

Upvotes: 2

Related Questions