Как получить новые/старые записи из сводной таблицы в BelongsToMany

Сортировка по новым/старым записям в своднйо таблице

По умолчанию отношение BelongsToMany в Laravel работает просто замечательно — вы можете легко прикреплять, откреплять и синхронизировать записи. Но, вдруг, вам понадобилось показать из сводной таблицы самые новые или самые старые записи? Эта статья расскажет как это сделать.

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

Файл миграции:

class CreateProjectUserPivotTable extends Migration
{
    public function up()
    {
        Schema::create('project_user', function (Blueprint $table) {
            $table->unsignedInteger('project_id');
            $table->foreign('project_id')->references('id')->on('projects');
            $table->unsignedInteger('user_id');
            $table->foreign('user_id')->references('id')->on('users');
        });
    }
}

Затем в модели, например в app/Project.php:

public function users()
{
    return $this->belongsToMany(User::class);
}

Как мы можем добавить поля автоинкремента или отметки времени, чтобы иметь возможность упорядочивать по самым новым или по самым старым сводным записям? Очень просто.

В миграции добавляем поля bigIncrements и timestamps:

Schema::create('project_user', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->unsignedInteger('project_id');
    $table->foreign('project_id')->references('id')->on('projects');
    $table->unsignedInteger('user_id');
    $table->foreign('user_id')->references('id')->on('users');
    $table->timestamps();
});

В модели нам не нужно добавлять что-либо в поле id, но для отметок времени есть специальный метод withTimestamps():

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

Теперь мы можем создать отдельные отношения, что-то типа этого:

public function newest_users()
{
    return $this->belongsToMany(User::class)->orderBy('id', 'desc');
}

В контроллере для списка проектов теперь мы можем сделать так:

$projects = Project::with('newest_users')->get();

А если вы хотите просмотреть пользователей проекта, начиная с самых новых, так:

@foreach($project->newest_users as $user)
    <span class="label">{{ $user->name }}</span>
@endforeach

Честно говоря, когда я писал эту статью, я понял, что поля меток времени в основном предназначены только для информации, их нельзя упорядочить по порядку, поскольку существует большая вероятность того, что синхронизация произойдет в течение одной секунды. Поэтому я советую упорядочить по полю id , который является автоинкрементом, и смотреть на временные метки, только если вам нужно узнать, когда была создана запись.

Автор: Povilas Korop
Перевод: Demiurge Ash