Вставьте новую запись, если она не существует, и обновите, если существует, laravel eloquent
есть ли какая-либо стенография для нас, чтобы вставить новую запись, если она не существует, и обновить запись, если она существует? ниже приведен код, который я использую.
$shopOwner = ShopMeta::where('shopId', '=', $theID)->where('metadataKey', '=', 2001)->first();
if ($shopOwner==null){
insert new record into database
} else {
update the existing record
}
спасибо
13 ответов:
вот полный пример того, о чем говорил" lu cip":
$user = User::firstOrNew(array('name' => Input::get('name'))); $user->foo = Input::get('foo'); $user->save();
Ниже приведена обновленная ссылка на документы, которая находится на последней версии Laravel
документы здесь: обновили ссылку
Обновлено: 27 Августа 2014 - [
updateOrCreate
встроена в ядро...]на всякий случай люди все еще сталкиваются с этим... Я узнал несколько недель после написания этого, что это на самом деле часть основного красноречивый фреймворк Laravel по...
копание в эквивалентный метод(ы) красноречивого. Вы можете посмотреть здесь:
https://github.com/laravel/framework/blob/4.2/src/Illuminate/Database/Eloquent/Model.php#L553
on: 570 и :553
/** * Create or update a record matching the attributes, and fill it with values. * * @param array $attributes * @param array $values * @return static */ public static function updateOrCreate(array $attributes, array $values = array()) { $instance = static::firstOrNew($attributes); $instance->fill($values)->save(); return $instance; }
Старый Ответ Ниже
мне интересно, есть ли какие-либо встроенные функции L4 для этого каким-то образом, например:
$row = DB::table('table')->where('id', '=', $id)->first(); // Fancy field => data assignments here $row->save();
Я создал этот метод несколько недель назад...
// Within a Model extends Eloquent public static function createOrUpdate($formatted_array) { $row = Model::find($formatted_array['id']); if ($row === null) { Model::create($formatted_array); Session::flash('footer_message', "CREATED"); } else { $row->update($formatted_array); Session::flash('footer_message', "EXISITING"); } $affected_row = Model::find($formatted_array['id']); return $affected_row; }
Я надеюсь, что это поможет. Я хотел бы видеть альтернативу этому, если у кого-то есть один, чтобы поделиться. @erikthedev_
а в Laravel >= 5.3, если кому-то все еще интересно, как это сделать простым способом. Его можно использовать с помощью:
updateOrCreate()
.например на вопрос, вы можете использовать что-то вроде:
$matchThese = array('shopId'=>$theID,'metadataKey'=>2001); ShopMeta::updateOrCreate($matchThese,['shopOwner'=>'New One']);
выше код будет проверять таблицу, представленную ShopMeta, которая будет, скорее всего,
shop_metas
если не определено иначе в самой моделии он будет пытаться найти запись с
колонки
shopId = $theID
и
колонки
metadateKey = 2001
и если он найдет, то он будет обновлять столбец
shopOwner
нашел строкуNew One
.если он находит более одной совпадающей строки, то он обновит самую первую строку, которая означает, что имеет самый низкий первичный
id
.если не найдено вообще, то он будет вставлять новую строку с :
shopId = $theID
,metadateKey = 2001
иshopOwner = New One
обратите внимание Проверьте свою модель для
$fillable
и сделать Сью у вас есть каждое имя столбца, определенное там, которое вы хотите вставить или обновить, а остальные столбцы имеют значение по умолчанию или егоid
столбец автоматически увеличивается на единицу.в противном случае он выдаст ошибку при выполнении примера выше:
Illuminate\Database\QueryException with message 'SQLSTATE[HY000]: General error: 1364 Field '...' doesn't have a default value (SQL: insert into `...` (`...`,.., `updated_at`, `created_at`) values (...,.., xxxx-xx-xx xx:xx:xx, xxxx-xx-xx xx:xx:xx))'
поскольку там будет какое-то поле, которое будет нуждаться в значении при вставке новой строки, и это не будет возможно, поскольку либо его не определено в
$fillable
или он не имеет значения по умолчанию.для получения дополнительной информации, пожалуйста, см. Документация Laravel на : https://laravel.com/docs/5.3/eloquent
один пример оттуда:
// If there's a flight from Oakland to San Diego, set the price to . // If no matching model exists, create one. $flight = App\Flight::updateOrCreate( ['departure' => 'Oakland', 'destination' => 'San Diego'], ['price' => 99] );
который в значительной степени очищает все.
надеюсь, это поможет
сохранить функция:
$shopOwner->save()
уже делать то, что вы хотите...
код Laravel:
// If the model already exists in the database we can just update our record // that is already in this database using the current IDs in this "where" // clause to only update this model. Otherwise, we'll just insert them. if ($this->exists) { $saved = $this->performUpdate($query); } // If the model is brand new, we'll insert it into our database and set the // ID attribute on the model to the value of the newly inserted row's ID // which is typically an auto-increment value managed by the database. else { $saved = $this->performInsert($query); }
$shopOwner = ShopMeta::firstOrNew(array('shopId' => $theID,'metadataKey' => 2001));
затем внесите изменения и сохраните. Обратите внимание, что firstOrNew не делает вставку, если она не найдена, если вам это нужно, то ее firstOrCreate.
firstOrNew
создаст запись, если она не существует, и обновит строку, если она уже существует. Вы также можете использоватьupdateOrCreate
вот полный пример$flight = App\Flight::updateOrCreate( ['departure' => 'Oakland', 'destination' => 'San Diego'], ['price' => 99] );
если есть рейс из Окленда в Сан-Диего, установили цену в $99. если не существует, создать новую строку
ссылка Doc здесь: (https://laravel.com/docs/5.5/eloquent)
еще один вариант, если Ваш идентификатор не является автоинкрементом, и вы знаете, какой из них вставить / обновить:
$object = MyModel::findOrNew($id); //assign attributes to update... $object->save();
на самом деле firstOrCreate не будет обновление в случае, если регистр уже существует в БД. Я немного улучшил решение Эрика, поскольку мне действительно нужно было обновить таблицу, которая имеет уникальные значения не только для столбца "id"
/** * If the register exists in the table, it updates it. * Otherwise it creates it * @param array $data Data to Insert/Update * @param array $keys Keys to check for in the table * @return Object */ static function createOrUpdate($data, $keys) { $record = self::where($keys)->first(); if (is_null($record)) { return self::create($data); } else { return self::where($keys)->update($data); } }
тогда вы бы использовали его так:
Model::createOrUpdate( array( 'id_a' => 1, 'foo' => 'bar' ), array( 'id_a' => 1 ) );
как @JuanchoRamone опубликовано выше (спасибо @Juancho) это очень полезно для меня, но если ваши данные массив вы должны изменить немного так:
public static function createOrUpdate($data, $keys) { $record = self::where($keys)->first(); if (is_null($record)) { return self::create($data); } else { return $record->update($data); } }
как метод firstOrCreate, updateOrCreate сохраняется модель, Так что нет необходимости вызывать метод save()
// If there's a flight from Oakland to San Diego, set the price to . // If no matching model exists, create one. $flight = App\Flight::updateOrCreate( ['departure' => 'Oakland', 'destination' => 'San Diego'], ['price' => 99] );
и для вашего вопроса
$shopOwner = ShopMeta::updateOrCreate( ['shopId' => $theID, 'metadataKey' => '2001'], ['other field' => 'val' ,'other field' => 'val', ....] );
разве это не то же самое, что updateOrCreate()?
это похоже, но не то же самое. В updateOrCreate() будет работать только для одной строки за раз, которая не позволяет массовую вставку. InsertOnDuplicateKey будет работать на многих строках.
Если вам нужна такая же функциональность с помощью
DB
, в Laravel>= 5.5
вы можете использовать:DB::table('table_name')->updateOrInsert($attributes, $values);
или сокращенная версия, когда
$attributes
и$values
то же самое:DB::table('table_name')->updateOrInsert($values);
проверьте, существует ли пользователь или нет. Если не вставить
$exist = DB::table('User')->where(['username'=>$username,'password'=>$password])->get(); if(count($exist) >0) { echo "User already exist";; } else { $data=array('username'=>$username,'password'=>$password); DB::table('User')->insert($data); } Laravel 5.4