Найти или Создать с Красноречивым

Недавно я начал работать с 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', ]); 

возвращает найденный экземпляр или новый экземпляр.