Найти или Создать с Красноречивым
Недавно я начал работать с Laravel и Eloquent, и мне было интересно, отсутствие возможности поиска или создания моделей. Вы всегда можете написать, например:
$user = User::find($id);
if (!$user) {
$user = new User;
}
Однако нет ли лучшего способа найти или создать? В примере это кажется тривиальным, но для более сложных ситуаций было бы очень полезно либо получить существующую запись, либо обновить ее, либо создать новую.
Ответы
Ответ 1
Ниже приведен оригинальный ответ для: 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
Ответ 2
В качестве альтернативы, в этом случае вы также можете использовать функцию Laravel и искать идентификатор в качестве атрибута, т.е.
$user = User::firstOrCreate(['id' => $id]);
Ответ 3
Модели Laravel 4 имеют встроенный findOrNew
метод, который делает то, что вам нужно:
$user = User::findOrNew($id);
Ответ 4
В Laravel 5:
Существует два метода, которые вы можете использовать для создания моделей путем присвоения атрибутов: firstOrCreate
и firstOrNew
.
Метод firstOrCreate
попытается найти запись базы данных, используя данные пары столбцов/значений. Если модель не может быть найдена в базе данных, запись будет вставлена с указанными атрибутами.
Метод firstOrNew
, например firstOrCreate
, попытается найти запись в базе данных, соответствующей данным атрибутам. Однако, если модель не найдена, экземпляр новой модели будет возвращен. Обратите внимание, что модель, возвращаемая firstOrNew
, еще не сохраняется в базе данных. Чтобы сохранить его, вам нужно будет вручную сохранить его.
// 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']);
Ответ 5
Найти или Создать на основе первичного ключа id
$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();
Ответ 6
Вы можете использовать firstOrCreate (он работает с Laravel 4.2)
$bucketUser = BucketUser::firstOrCreate([
'bucket_id' => '1',
'user_id' => '2',
]);
возвращает найденный экземпляр или новый экземпляр.