创建和更新Laravel Eloquent

1my*_*myb 142 php laravel eloquent laravel-query-builder

如果新记录不存在,插入新记录或更新的简写是什么?

<?php

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

if ($shopOwner == null) {
    // Insert new record into database
} else {
    // Update the existing record
}
Run Code Online (Sandbox Code Playgroud)

weo*_*tch 217

以下是"lu cip"所讨论的完整示例:

$user = User::firstOrNew(array('name' => Input::get('name')));
$user->foo = Input::get('foo');
$user->save();
Run Code Online (Sandbox Code Playgroud)

以下是Laravel最新版本中文档的更新链接

文档:更新链接

  • 我们也可以通过使用if($ user-&gt; exists)来检查$ user是新的还是被回收的。 (2认同)

Eri*_*bar 77

更新:2014年8月27日 - [ updateOrCreate内置于核心...]

以防人们仍然遇到这个问题......我在写完这篇文章几个星期后发现,这实际上是Laravel的Eloquent核心的一部分......

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

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;
    }
Run Code Online (Sandbox Code Playgroud)

下面的旧答案


我想知道是否有任何内置的L4功能以某种方式执行此操作,例如:

$row = DB::table('table')->where('id', '=', $id)->first();
// Fancy field => data assignments here
$row->save();
Run Code Online (Sandbox Code Playgroud)

几个星期前我确实创造了这种方法......

// 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;
}
Run Code Online (Sandbox Code Playgroud)

我希望有所帮助.如果有人可以分享,我很乐意看到替代品.@erikthedev_

  • 请注意Laravel不会将其作为事务运行,因此如果您有唯一的密钥而另一个用户同时使用相同的密钥创建它,则可能会出现异常.我相信RedBeanPHP的一个优点是这种类型的事情是在一个事务中完成的. (3认同)

Lea*_*ner 52

正如Laravel> = 5.3,如果有人仍然好奇如何以简单的方式这样做.它可以通过使用:updateOrCreate().

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

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

上面的代码将检查ShopMeta所代表的表格,shop_metas除非模型本身没有另外定义,否则很可能会这样

它会尝试找到条目

shopId = $theID

metadateKey = 2001

如果它找到,那么它将更新shopOwner找到的行的列New One.

如果它找到多个匹配的行,那么它将更新第一行,这意味着哪个行具有最低的主要行id.

如果根本找不到,那么它将插入一个新行:

shopId = $theID,metadateKey = 2001shopOwner = New One

注意 检查您的模型,$fillable并确定您要在其中定义要插入或更新的每个列名称,并且休息列具有默认值或其id列自动递增1.

否则在执行上面的示例时会抛出错误:

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))'
Run Code Online (Sandbox Code Playgroud)

因为在插入新行时会有一些需要值的字段,因为它没有被定义,$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]
);
Run Code Online (Sandbox Code Playgroud)

这几乎清除了一切.

我希望它有所帮助


lu *_*cip 16

保存功能:

$shopOwner->save()
Run Code Online (Sandbox Code Playgroud)

已经做你想要的......

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);
    }
Run Code Online (Sandbox Code Playgroud)

  • 这看起来不像是一个原子upsert操作.如果不是,这可能会导致竞争条件. (6认同)

Sae*_*ari 13

firstOrNew将创建记录(如果不存在)并更新行(如果已存在).你也可以updateOrCreate在这里使用完整的例子

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

如果有从奥克兰飞往圣地亚哥的航班,请将价格定为99美元.如果不存在则创建新行

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


mal*_*hal 5

$shopOwner = ShopMeta::firstOrNew(array('shopId' => $theID,'metadataKey' => 2001));
Run Code Online (Sandbox Code Playgroud)

然后进行更改并保存.请注意,如果找不到插入,则firstOrNew不会执行插入,如果您确实需要插入其firstOrCreate.


Sas*_*vic 5

如果您需要使用来提供相同的功能DB,请在Laravel >= 5.5中使用:

DB::table('table_name')->updateOrInsert($attributes, $values);
Run Code Online (Sandbox Code Playgroud)

或简写版本,当$attributes$values相同时:

DB::table('table_name')->updateOrInsert($values);
Run Code Online (Sandbox Code Playgroud)