Avatar ·

Как получить ID последней вставленной записи в Laravel Eloquent?

Всем привет! Я только начал изучать Laravel и столкнулся с проблемой. У меня есть простая форма регистрации пользователей на сайте. После того как пользователь заполняет форму и отправляет данные, я сохраняю их в базу данных через Eloquent. Но мне нужно сразу после сохранения получить ID этой новой записи, чтобы, например, создать профиль пользователя или сразу перенаправить его на страницу с этим ID. Вот мой текущий код: ```php public function store(Request $request) { $user = new User(); $user->name = $request->input('name'); $user->email = $request->input('email'); $user->password = Hash::make($request->input('password')); $user->save(); // Как мне здесь получить ID только что вставленной записи? // Пробовал $user->id, но он возвращает null // Пробовал DB::getPdo()->lastInsertId(), но это не работает с Eloquent return redirect()->route('profile.show', ['id' => ???]); } ``` Я перепробовал несколько вариантов: и через свойство `id` после `save()`, и через глобальную функцию `lastInsertId()`, но ничего не работает правильно. Подскажите, как правильно получить ID последней вставленной записи в Laravel? Желательно с примером кода. Заранее спасибо! P.S. Использую Laravel 10, MySQL. <<>>

Основное решение: используйте свойство id после save()

В Laravel Eloquent получить ID последней вставленной записи очень просто. После вызова метода save() на модели, свойство id автоматически заполняется значением, которое присвоила база данных. Ваша проблема в том, что вы, вероятно, проверяете $user->id до вызова save(), либо используете неправильное обращение к свойству.

Вот правильный код:

public function store(Request $request)
{
    $user = new User();
    $user->name = $request->input('name');
    $user->email = $request->input('email');
    $user->password = Hash::make($request->input('password'));
    $user->save();

    // После save() свойство id уже заполнено!
    $lastInsertedId = $user->id;

    return redirect()->route('profile.show', ['id' => $lastInsertedId]);
}

Важно: метод save() не только вставляет запись, но и обновляет модель в памяти, присваивая ей ID из базы данных. Поэтому $user->id будет содержать корректное значение сразу после вызова save().

Альтернативный способ: метод create()

Если вы используете массовое присвоение, то можете применить метод create(), который возвращает созданную модель:

public function store(Request $request)
{
    $user = User::create([
        'name' => $request->input('name'),
        'email' => $request->input('email'),
        'password' => Hash::make($request->input('password')),
    ]);

    // $user уже содержит ID
    $lastInsertedId = $user->id;

    return redirect()->route('profile.show', ['id' => $lastInsertedId]);
}

Что делать, если ID не возвращается?

Если свойство id остаётся пустым после save(), проверьте следующее:

  • Поле ID в модели: Убедитесь, что в вашей модели User свойство $primaryKey установлено правильно (по умолчанию 'id'). Если вы используете другое имя для первичного ключа, укажите его:
protected $primaryKey = 'user_id'; // если ваш ключ называется user_id
  • Инкремент: Убедитесь, что поле ID в таблице базы данных имеет тип BIGINT AUTO_INCREMENT (или аналогичный). Если вы вставляете ID вручную, Eloquent может не обновить модель.
  • Трейт HasUuids или HasUlids: Если вы используете UUID или ULID вместо автоинкремента, то ID генерируется до вставки, и он доступен сразу после создания объекта модели. В этом случае $user->id будет работать даже до save().

Дополнительный совет: получение ID при вставке через Query Builder

Если вы по какой-то причине не используете Eloquent, а работаете напрямую с Query Builder, то ID можно получить так:

use Illuminate\Support\Facades\DB;

$id = DB::table('users')->insertGetId([
    'name' => $request->input('name'),
    'email' => $request->input('email'),
    'password' => Hash::make($request->input('password')),
]);

// $id содержит ID последней вставленной записи

Метод insertGetId() возвращает ID вставленной записи. Это удобно, когда вы не хотите создавать экземпляр модели.

Итог

Самый простой и правильный способ в Laravel — это использовать свойство id модели после вызова save() или метода create(). Это работает в 99% случаев. Если нет — проверьте настройки первичного ключа и структуру таблицы.

<<>>

Использование события saved или created

Если вам нужно выполнить какие-то действия сразу после создания записи и получить ID, можно использовать события Eloquent. Это особенно полезно, если логика получения ID выносится в отдельную обработку.

use App\Models\User;
use Illuminate\Support\Facades\Hash;

public function store(Request $request)
{
    $user = new User();
    $user->name = $request->input('name');
    $user->email = $request->input('email');
    $user->password = Hash::make($request->input('password'));

    // Подписываемся на событие saved
    $user->saved(function ($model) {
        // Здесь $model->id уже доступен
        \Log::info('Новый пользователь с ID: ' . $model->id);
    });

    $user->save();

    // ID также доступен и здесь
    return redirect()->route('profile.show', ['id' => $user->id]);
}

Также можно использовать глобальные события в модели, определив метод boot():

class User extends Model
{
    protected static function boot()
    {
        parent::boot();

        static::created(function ($user) {
            // Здесь $user->id уже заполнен
            // Можно, например, создать профиль
            Profile::create(['user_id' => $user->id]);
        });
    }
}

Этот подход хорош тем, что отделяет логику от контроллера и делает код чище. Особенно рекомендуется, если после создания пользователя нужно выполнить несколько действий (создать профиль, отправить письмо, записать в лог).