Laravel Eloquent: Как заказать результаты связанных моделей?

У меня есть модель под названием Школа, и у нее много Студентов.

Вот код в моей модели:

public function students()
{
    return $this->hasMany('Student');
}

Я получаю все ученики с этим кодом в контроллере:

$school = School::find($schoolId);

и в представлении:

@foreach ($school->students as $student)

Теперь я хочу заказать Студенты по какому-либо полю в таблице students. Как я могу это сделать?

Ответ 1

У вас есть несколько способов добиться этого:

// when eager loading
$school = School::with(['students' => function ($q) {
  $q->orderBy('whateverField', 'asc/desc');
}])->find($schoolId);

// when lazy loading
$school = School::find($schoolId);
$school->load(['students' => function ($q) {
  $q->orderBy('whateverField', 'asc/desc');
}]);

// or on the collection
$school = School::find($schoolId);
// asc
$school->students->sortBy('whateverProperty');
// desc
$school->students->sortByDesc('whateverProperty');


// or querying students directly
$students = Student::whereHas('school', function ($q) use ($schoolId) {
  $q->where('id', $schoolId);
})->orderBy('whateverField')->get();

Ответ 2

Вы можете добавить orderBy в ваши отношения, поэтому единственное, что вам нужно изменить, это

public function students()
{
    return $this->hasMany('Student');
}

в

public function students()
{
    return $this->hasMany('Student')->orderBy('id', 'desc');
}

Ответ 3

Чтобы ответить на исходный вопрос, динамическое свойство students также можно получить в качестве метода отношений.

Итак, у вас есть это, чтобы получить всех учеников:

$students = $school->students;

Теперь, как метод отношений, это эквивалентно:

$students = $school->students()->get();

Учитывая это, теперь вы можете добавить в некоторый порядок:

$students = $school->students()->orderBy('students.last_name')->get();

Так как eloquent будет выполнять соединение, обязательно включите имя таблицы, когда ссылаетесь на столбец для заказа.

Вы также можете добавить это к вашему методу students, если вы хотите установить порядок по умолчанию, который $school->students всегда будет возвращен. Ознакомьтесь с документацией для hasMany(), чтобы узнать, как это работает.

Ответ 4

Для многих отношение к одному я нашел один ответ на:

https://laracasts.com/discuss/channels/eloquent/order-by-on-relationship

$order = 'desc';
$users = User::join('roles', 'users.role_id', '=', 'roles.id')
  ->orderBy('roles.label', $order)
  ->select('users.*')
  ->paginate(10);

это может спасти день... кого угодно

Ответ 5

Вы можете использовать это так:

$students = $school->students()->orderBy('id', 'desc');

Вы также можете использовать

$students = $school->students()->orderBy('id', 'desc')->paginate(10);