【问题标题】:Laravel Update if record exists or Create if notLaravel 如果记录存在则更新,如果不存在则创建
【发布时间】:2016-01-13 08:28:15
【问题描述】:

我想更新我的记录(如果存在),但如果不存在则创建新记录。这是我到目前为止:

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

它运行良好。

但据我所知,Laravel 因其雄辩的模型而非常强大。 我可以让它更短吗?还是我已经做对了?

我尝试使用“updateOrCreate”方法,但我的外键“merchant_branch_id”需要填写。

【问题讨论】:

    标签: php laravel laravel-5


    【解决方案1】:

    Laravel 已经通过 save 函数使用了这种方法

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

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

    ->exists

    所有 laravel 模型都有一个 ->exists 属性。

    更具体地说,如果模型是从数据库加载的,或者自创建后已保存到数据库中,exists 属性将为 true;否则为假。

    如果您了解->exists,您可以使用它,但这是处理此类要求的另一种方法。

    另一种方式。

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

    【讨论】:

    • 嗨。对不起,但我不明白这一点。你介意再解释一下吗?
    • 我认为您必须阅读一些与$this->exists 工作原理相关的代码文档...
    • @sstarlight 请看看我更新的答案。
    • 我已经尝试过使用 updateOrCreate 的第二种方法,但我的外键约束失败,因为 MerchantToken 中的 Merchant_branch_id 不可填写。存在我认为它几乎和我现在做的一样。使用“如果”
    • 数据库可能已经包含具有相同主键值的记录(通常为id)。然后save() 会很乐意尝试insert(而不是update)并因错误而失败(唯一约束)。
    【解决方案2】:

    Laravel 为此提供方法updateOrCreate

    • 如果有从奥克兰到圣地亚哥的航班,请将价格设置为 99 美元。

    • 如果不存在匹配的模型,则创建一个。

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

    【讨论】:

    • 如果在数据库中定义主键,则必须在模型中定义 $primaryKey = 'flight_id';
    • 如果有从奥克兰飞往圣地亚哥的机票,价格为 $99 会怎样?
    • 实际上,我很确定它根本不会发送更新。通常 eloquent 会在保存之前检查 isDirty() 属性。我错了吗?
    【解决方案3】:

    添加新功能代码:

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

    【讨论】:

    • 谢谢,这是我要找的代码,其他的没有意义,我需要像这段代码一样检查单个值。
    猜你喜欢
    • 2018-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多