簡體   English   中英

創建和更新 Laravel Eloquent

[英]Creating and Update 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
}

這是“lu cip”所談論的完整示例:

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

以下是最新版本的 Laravel 文檔的更新鏈接

文檔在這里:更新的鏈接

更新時間:2014 年 8 月 27 日 - [ updateOrCreate內置於核心...]

以防萬一人們仍然遇到這個……我在寫這篇文章幾周后發現,這實際上是 Laravel 的 Eloquent 核心的一部分……

深入研究 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_

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

這幾乎清除了一切。

查詢生成器更新

有人問是否可以在 Laravel 中使用 Query Builder。 是 Laravel 文檔中查詢生成器的參考。

Query Builder 的工作原理與 Eloquent 完全相同,因此任何適用於 Eloquent 的內容也適用於 Query Builder。 因此,對於這種特定情況,只需對查詢構建器使用相同的函數,如下所示:

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

當然,不要忘記添加DB Facade:

use Illuminate\Support\Facades\DB;

要么

use DB;

如果不存在,則firstOrNew將創建記錄,如果已存在則更新行。 你也可以使用updateOrCreate這里是完整的例子

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

如果有從奧克蘭飛往聖地亞哥的航班,請將價格設置為 99 美元。 如果不存在創建新行

參考文檔在這里:( https://laravel.com/docs/5.5/eloquent

保存功能:

$shopOwner->save()

已經做你想做的...

拉維爾代碼:

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

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

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

$attributes$values相同時的簡寫版本:

DB::table('table_name')->updateOrInsert($values);
$shopOwner = ShopMeta::firstOrNew(array('shopId' => $theID,'metadataKey' => 2001));

然后進行更改並保存。 請注意,如果未找到,則 firstOrNew 不會執行插入,如果您確實需要,則它的 firstOrCreate。

與 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', ....]
);

如果您的 id 不是自動增量並且您知道要插入/更新哪一個,則還有一種選擇:

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

實際上,如果數據庫中已存在寄存器,則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
        )
);

就像上面發布的@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);
    }
}

這不是和 updateOrCreate() 一樣嗎?

它相似但不相同。 updateOrCreate() 一次只能處理一行,不允許批量插入。 InsertOnDuplicateKey 將適用於多行。

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

嘗試更多的參數,一個肯定會找到,如果可用更新,而不是它會創建新的

$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,
                ]);

檢查用戶是否存在。 如果不插入

$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           

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM