Eloquent: использование find() и where() в laravel

Я пытаюсь получить запись из таблицы базы данных posts, используя ее идентификатор. Я довольно долго ломал голову над методом find(), не понимая, почему он не работает. Вот мой запрос, который выглядит правильно для меня, но не работает:

$post = Post::find($id);
$post->delete();

Неохотно я сделал это:

$post = Post::where('id', $id);
$post->delete();

и как ни странно, это сработало, но я понятия не имею, как.

Я также знаю, что в отличие от find(), where() — это построитель запросов, поэтому я мог бы использовать его и так: Post::where('id', $id)->first()

Любые идеи о разнице в том, как работают методы?


person Awa Melvine    schedule 21.11.2016    source источник


Ответы (3)


Ваш код выглядит нормально, но есть несколько вещей, о которых нужно знать:

Post::find($id); действует на первичный ключ, если вы установили первичный ключ в своей модели на что-то отличное от id, выполнив:

protected  $primaryKey = 'slug';

тогда find будет искать по этому ключу.

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

public $incrementing = false;
person craig_h    schedule 22.11.2016
comment
Однако есть существенные различия в выполнении процесса удаления. Если вы используете экземпляр модели для удаления, то есть $post-›delete(), выполняются два запроса. Один для извлечения записи из базы данных с помощью метода find(), а второй для удаления записи. При использовании построителя запросов выполняется только один запрос, экземпляр модели никогда не создается. В результате никакие функции модели Post работать не будут. Например, если у вас есть прослушиватель событий удаления модели, он не будет выполнен. - person Ahmed Shefeer; 24.07.2018
comment
Ответ Ахмеда следует выделить, так как разница может вызвать много путаницы. - person Mathieu Bour; 15.05.2019

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

public $keyType = 'string'

Eloquent понимает любой из типов, определенных в функции castAttribute(), которыми в Laravel 5.4 являются: int, float, string, bool, object, array, collection, date и timestamp.

Это гарантирует, что ваш первичный ключ будет правильно преобразован в эквивалентный тип данных PHP.

person SlyDave    schedule 20.07.2017

Не найдено исключений

Иногда вы можете захотеть создать исключение, если модель не найдена. Это особенно полезно в маршрутах или контроллерах. Методы findOrFail и firstOrFail получат первый результат запроса. Однако, если результат не найден, будет выброшено Illuminate\Database\Eloquent\ModelNotFoundException:

$model = App\Flight::findOrFail(1);

$model = App\Flight::where('legs', '>', 100)->firstOrFail();

Если исключение не перехвачено, пользователю автоматически отправляется HTTP-ответ 404. Нет необходимости писать явные проверки для возврата ответов 404 при использовании этих методов:

Route::get('/api/flights/{id}', function ($id) {
    return App\Flight::findOrFail($id);
});
person Miqayel    schedule 08.12.2019