IT story

Laravel Eloquent 생성 및 업데이트

hot-time 2020. 6. 23. 07:21
반응형

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

도움이 되길 바랍니다. 누군가 공유 할 것이 있다면 이것에 대한 대안을보고 싶습니다. 아리따움


마찬가지로 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 and shopOwner = New One

Notice Check your model for $fillable and make sue that you have every column name defined there which you want to insert or update and rest columns have either default value or its id column auto incremented one.

Otherwise it will throw error when executing above example:

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))'

As there would be some field which will need value while inserting new row and it will not be possible as either its not defined in $fillable or it doesnt have default value.

For more reference please see Laravel Documentation at : https://laravel.com/docs/5.3/eloquent

One example from there is:

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

which pretty much clears everything.

Query Builder Update

Someone has asked if it is possible using Query Builder in Laravel. Here is reference for Query Builder from Laravel docs.

Query Builder works exactly the same as Eloquent so anything which is true for Eloquent is true for Query Builder as well. So for this specific case, just use the same function with your query builder like so:

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

Of course, don't forget to add DB facade:

use Illuminate\Support\Facades\DB;

OR

use DB;

I hope it helps


Save function:

$shopOwner->save()

already do what you want...

Laravel code:

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

firstOrNew will create record if not exist and updating a row if already exist. You can also use updateOrCreate here is the full example

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

If there's a flight from Oakland to San Diego, set the price to $99. if not exist create new row

Reference Doc here: (https://laravel.com/docs/5.5/eloquent)


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

Then make your changes and save. Note the firstOrNew doesn't do the insert if its not found, if you do need that then its firstOrCreate.


If you need the same functionality using the DB, in Laravel >= 5.5 you can use:

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

or the shorthand version when $attributes and $values are the same:

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

One more option if your id isn't autoincrement and you know which one to insert/update:

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

Actually firstOrCreate would not update in case that the register already exists in the DB. I improved a bit Erik's solution as I actually needed to update a table that has unique values not only for the column "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);
    }
}

Then you'd use it like this:

Model::createOrUpdate(
        array(
    'id_a' => 1,
    'foo' => 'bar'
        ), array(
    'id_a' => 1
        )
);

like @JuanchoRamone posted above (thank @Juancho) it's very useful for me, but if your data is array you should modify a little like this:

public static function createOrUpdate($data, $keys) {
    $record = self::where($keys)->first();
    if (is_null($record)) {
        return self::create($data);
    } else {
        return $record->update($data);
    }
}

Like the firstOrCreate method, updateOrCreate persists the model, so there's no need to call 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]
);

And for your issue

$shopOwner = ShopMeta::updateOrCreate(
   ['shopId' => $theID, 'metadataKey' => '2001'],
   ['other field' => 'val' ,'other field' => 'val', ....]
);

Isn't this the same as updateOrCreate()?

It is similar but not the same. The updateOrCreate() will only work for one row at a time which doesn't allow bulk insert. InsertOnDuplicateKey will work on many rows.

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


check if a user exists or not. If not insert

$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           

참고URL : https://stackoverflow.com/questions/18839941/creating-and-update-laravel-eloquent

반응형