创建和更新 Laravel Eloquent

插入新记录或更新已存在记录的简写是什么?

<?php


$shopOwner = ShopMeta::where('shopId', '=', $theID)
->where('metadataKey', '=', 2001)->first();


if ($shopOwner == null) {
// Insert new record into database
} else {
// Update the existing record
}
433650 次浏览

保存功能:

$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);
}

更新: 2014年8月27日-[ updateOrCreate嵌入核心... ]

为了防止人们还在读这本书,我在写这本书的几个星期后发现,这实际上是 Laravel 的雄辩的核心的一部分..。

深入研究 Eloquent 的等效方法,你可以在这里看到:

Https://github.com/laravel/framework/blob/4.2/src/illuminate/database/eloquent/model.php#l553

电话: 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 _

下面是“ lu cip”所说的一个完整的例子:

$user = User::firstOrNew(array('name' => Input::get('name')));
$user->foo = Input::get('foo');
$user->save();

以下是最新版本的 Laravel 文件的最新连结

这里是医生: 更新链接

$shopOwner = ShopMeta::firstOrNew(array('shopId' => $theID,'metadataKey' => 2001));

然后进行更改并保存。注意,如果没有找到 firstOrNew,则 firstOrNew 不执行插入操作,如果需要,则执行 firstOrCreate。

实际上,在数据库中已经存在寄存器的情况下,FirstOrCreate不会使用 更新。 我稍微改进了 Erik 的解决方案,因为我实际上需要更新一个不仅对“ 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
)
);

比如上面发布的@JuanchorRamone (谢谢@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);
}
}

2020年最新情况

如同在 Laravel > = 5.3中,如果有人仍然好奇如何以简单的方式做到这一点,可以使用: updateOrCreate()

例如,对于提出的问题,您可以使用以下内容:

$matchThese = ['shopId'=>$theID,'metadataKey'=>2001];
ShopMeta::updateOrCreate($matchThese,['shopOwner'=>'New One']);

上面的代码将检查由 ShopMeta 表示的表,除非在模型本身中没有另外定义,否则最有可能是 shop_metas

它会试图找到入口

shopId = $theID

还有

metadateKey = 2001

如果它发现然后它将更新列 shopOwner的发现行到 New One

如果它找到多个匹配行,那么它将更新第一行,这意味着主 id最低。

如果完全找不到,它将插入一个新行,其中包含:

shopId = $theIDmetadateKey = 2001shopOwner = 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 $99.
// If no matching model exists, create one.
$flight = App\Flight::updateOrCreate(
['departure' => 'Oakland', 'destination' => 'San Diego'],
['price' => 99]
);

基本上什么都没有了。

查询生成器更新

有人问是否可以在 Laravel 使用 Query Builder。给你是 Laravel 文档中查询生成器的参考。

QueryBuilder 的工作原理与 Eloquent 完全相同,因此任何对 Eloquent 成立的工作原理对 QueryBuilder 来说都是成立的。因此,对于这个特定的情况,只需对查询构建器使用相同的函数,如下所示:

$matchThese = array('shopId'=>$theID,'metadataKey'=>2001);
DB::table('shop_metas')::updateOrCreate($matchThese,['shopOwner'=>'New One']);

当然,不要忘记添加 DB facade:

use Illuminate\Support\Facades\DB;

或者

use DB;

检查用户是否存在。如果没有插入

$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

如果你的 id 不是自动递增的,并且你知道应该插入/更新哪一个,还有一个选项:

$object = MyModel::findOrNew($id);
//assign attributes to update...
$object->save();

如果不存在,firstOrNew 将创建记录,如果已经存在,则更新行。 你也可以在这里使用 updateOrCreate完整的例子

$flight = App\Flight::updateOrCreate(
['departure' => 'Oakland', 'destination' => 'San Diego'],
['price' => 99]
);

如果有一个航班从奥克兰到圣地亚哥,设置的价格为99美元。如果不存在创建新行

参考文件(https://laravel.com/docs/5.5/eloquent)

与 firstOrCreate 方法一样,UpdateOrCreate持久化模型 所以不需要调用 save ()

// If there's a flight from Oakland to San Diego, set the price to $99.
// 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 将在许多行上工作。

Https://github.com/yadakhov/insert-on-duplicate-key

如果你需要使用 DB的相同功能,在 Laravel >= 5.5中你可以使用:

DB::table('table_name')->updateOrInsert($attributes, $values);

如果 $attributes$values是相同的,则使用简写形式:

DB::table('table_name')->updateOrInsert($values);

尝试更多的参数一,一定会找到,如果可用的更新和不然,它将创建新的

$save_data= Model::firstOrNew(['key1' => $key1value,'key'=>$key2value]);
//your values here
$save_data->save();

UpdateOrCreate 方法意味着通过检查 where 条件进行更新或创建。
它很简单,在代码中你可以看到,在用户表中,它将检查一个电子邮件是否有值 $user->email,然后它将更新数据(这是在第二个参数作为一个数组) ,或者它将根据它创建一个数据。

$newUser = User::updateOrCreate(['email' => $user->email],[
'name' => $user->getName(),
'username' => $user->getName().''.$user->getId(),
'email' => $user->getEmail(),
'phone_no' => '',
'country_id' => 0,
'email_verified_at' => Carbon::now()->toDateTimeString(),
'is_email_verified' => 1,
'password'=>Hash::make('Secure123$'),
'avatar' => $user->getAvatar(),
'provider' => 'google',
'provider_id' => $user->getId(),
'access_token' => $user->token,
]);