Недавно я начал работать с Laravel и Eloquent , и мне было интересно узнать о нехватке находки или создать вариант для моделей. Вы всегда можете написать, например:
$user = User::find($id); if (!$user) { $user = new User; }
Однако нет ли лучшего способа найти или создать? В примере это кажется тривиальным, но для более сложных ситуаций было бы очень полезно либо получить существующую запись, либо обновить ее, либо создать новую.
Ниже приведен оригинальный ответ для: laravel-4
Уже существует метод findOrFail
доступный в Laravel
и когда этот метод используется, он выдает ModelNotFoundException
при неудаче, но в вашем случае вы можете сделать это, создав метод в своей модели, например, если у вас есть модель User
тогда вы просто поместите это функции в модели
// Put this in any model and use // Modelname::findOrCreate($id); public static function findOrCreate($id) { $obj = static::find($id); return $obj ?: new static; }
С вашего контроллера вы можете использовать
$user = User::findOrCreate(5); $user->first_name = 'Jhon'; $user->last_name = 'Doe'; $user->save();
Если пользователь с id
od 5
является exixts, он будет обновлен, иначе будет создан новый пользователь, но id
будет last_user_id + 1
(автоматически увеличивается).
Это другой способ сделать то же самое:
public function scopeFindOrCreate($query, $id) { $obj = $query->find($id); return $obj ?: new static; }
Вместо создания статического метода вы можете использовать scope
в Модели, поэтому метод в Model
будет scopeMethodName
и вызовет Model::methodName()
, как и в статическом методе, например
$user = User::findOrCreate(5);
firstOrCreate
доступен в Laravel 5x
, ответ слишком стар, и он был дан для Laravel-4.0
в 2013
.
В Laravel 5.3 метод firstOrCreate
имеет следующее объявление:
public function firstOrCreate(array $attributes, array $values = [])
Это означает, что вы можете использовать его так:
User::firstOrCreate(['email' => $email], ['name' => $name]);
Существо пользователя будет проверяться только по электронной почте, но при его создании новая запись сохранит как электронную почту, так и имя.
Документы API
В качестве альтернативы, в этом случае вы также можете использовать функцию Laravel и искать идентификатор в качестве атрибута, т.е.
$user = User::firstOrCreate(['id' => $id]);
Модели Laravel 4 имеют встроенный метод findOrNew
который делает то, что вам нужно:
$user = User::findOrNew($id);
В Laravel 5:
Существует два метода, которые вы можете использовать для создания моделей путем присвоения атрибутов: firstOrCreate
и firstOrNew
.
Метод firstOrCreate
попытается найти запись базы данных с использованием заданных пар столбца / значения. Если модель не может быть найдена в базе данных, запись будет вставлена с указанными атрибутами.
Метод firstOrNew
, такой как firstOrCreate
, попытается найти запись в базе данных, соответствующей заданным атрибутам. Однако, если модель не найдена, будет возвращен экземпляр новой модели . Обратите внимание, что модель, возвращаемая firstOrNew
, еще не сохраняется в базе данных. Чтобы сохранить его, вам необходимо вызвать save вручную:
// Retrieve the flight by the attributes, or create it if it doesn't exist... $flight = App\Flight::firstOrCreate(['name' => 'Flight 10']); // Retrieve the flight by the attributes, or instantiate a new instance... $flight = App\Flight::firstOrNew(['name' => 'Flight 10']);
Найти или Создать на основе идентификатора первичного ключа
$user = User::findOrNew($id); // if exist then update else insert $user->name= $data['full_name']; $user->save();
Первый или Новый на основе непервичного ключевого файла
// get the record where field_name=value else insert new record $user = User::firstOrNew(['field_name'=>'value']); $user->name= $data['full_name']; $user->save();
Первый или Новый на основе непервичного ключа
// get the record where field_name1=value1 and field_name2=value2, else insert new record $user = User::firstOrNew(['field_name1'=>'value1','field_name2'=>'value2']); $user->name= $data['full_name']; $user->save();
Вы можете использовать firstOrCreate (он работает с Laravel 4.2)
$bucketUser = BucketUser::firstOrCreate([ 'bucket_id' => '1', 'user_id' => '2', ]);
возвращает найденный экземпляр или новый экземпляр.