15

I want to update my record if it exists but create new one if not exists. here is i got so far:

 MerchantBranch.php
public function token()
{
   return $this->hasOne('App\MerchantBranchToken');
}

MerchantBranchToken.php
public function merchant_branch()
{
   return $this->belongsTo('App\MerchantBranch');
}

$find = MerchantBranchToken::find($id);

    if (!$find) {
        $branch = new MerchantBranchToken(['token' => $token]);
        MerchantBranch::find($id)->token()->save($branch);
    } else {
        $find->token = $token;
        $find->save();
    }  

It's working perfectly.

But as i know Laravel is very powerful for its eloquent model. Can I make it shorter? or i already doing it correctly?.

I've tried using "updateOrCreate" method but my foreign key "merchant_branch_id" need to be fillable.

4 Answers 4

33

Laravel provide method updateOrCreate for that purpose

  • 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]
);
Sign up to request clarification or add additional context in comments.

4 Comments

If you define primary key in database, you must define it in model protected $primaryKey = 'flight_id';
what happens if there is a flight from Oakland to San Diego with the price of $99 ?
Actually, I'm pretty sure it would not send an update at all. Normally eloquent will check the isDirty() property before saving. Am I wrong about this?
In that example, if there was already a flight OAK to SAN at 99, it would update the price to 99, from 99. If you set 'price' => 199, it would update the price to 199.
8

Laravel already using this methodology by save function

$user->save()

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

https://github.com/laravel/framework/blob/5.1/src/Illuminate/Database/Eloquent/Model.php#L1491

->exists

All laravel models have a ->exists property.

More specifically if the model is either loaded from the database, or has been saved to the database since being created the exists property will be true; Otherwise it will be false.

If you understand the ->exists you can use it but here is the another way to deal such requirement.

another way.

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

5 Comments

Hi. Sorry but i don't get the point. Would you mind explain it a little bit more?
I think you have to read some code documentation related to $this->exists how its work...
@sstarlight please have a look to my updated answer.
I've tried second way using updateOrCreate but i got foreign key constraint fails because my merchant_branch_id at MerchantToken is not fillable. Exists i think its almost same way like i do right now. using "if"
The database could already contain a record with the same primary key value (usually id). save() would then happily try to insert (instead of update) and fail with an error (unique constraint).
0

very simple.

first find record then remove if exist and insert again

$record = Model::where(['id'=>1]);
if ($record->exists()) {
        $record->delete();
}
Model::create($request->all());

2 Comments

it doesn't work because after delete record. id will be 2. you should use it Model::findOrFail(1)->update($request->all());
Model::updateOrCreate([...]) is the Laravel standard way to do this. No need to make three separate calls for this single action. Most databases support this as a single call.
-1

Add new function code :

vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php :

  public function updateOrInsert(array $attributes, array $values = [])
    {
        $instance = $this->where($attributes);
        if ($instance->count() != 0) {
            $instance->update($values);
        } else {
            $instance = $this->updateOrCreate($attributes, $values);
        }
        return $instance;
    }

1 Comment

thank you, this is the code I'm looking for, the others are meaningless, I need to check for a single value as in this code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.