如何在 Laravel5 中软删除时将 Null 设置为相关 table 记录

How to set Null to the related table record on soft delete in Laravel5

我是 Laravel 的新手。

我有两个 table 彼此相关。

我想在其他相关 table 记录被软删除时将相关 table 记录设置为 null。

我知道如何在其他相关table记录时软删除,但我如何设置空而不是软删除?

产品型号(已编辑)

class Product extends Model
{
    use SoftDeletes;
    protected $dates = ['deleted_at'];

    public $table = "products";

    public function projects()
    {

        return $this->hasMany("App\Model\Project");

    }


    public static function boot(){

        parent::boot();

        static::deleted(function($product)
        {

            //set null
            $product->projects()->setNull();

        });

    }

}

项目模型(已编辑)

<?php

    class Project extends Model
    {
        use SoftDeletes;
        protected $dates = ['deleted_at'];

        public function product()
        {
            return $this->belongsTo("App\Model\Product");

        }

        public function setNull()
        {

            $this->product_id = NULL;
            $this->save();

        }

    }

Table 架构

        Schema::create('projects', function (Blueprint $table) {

            $table->increments('id');

            $table->string('project_name')->unique("project_name");
            $table->integer('project_value')->unsigned();


            $table->integer('product_id')->unsigned()->nullable(); 
            $table->foreign('product_id')->references('id')->on('products')->onDelete("set null");

            $table->timestamps();
            $table->softDeletes();

            $table->engine = 'InnoDB';

        });

注意

一个项目属于一个产品。好像有点怪,不过没关系。

错误信息

当我删除一条产品记录时,出现以下错误。

[2017-05-13 17:25:28] local.ERROR: BadMethodCallException: Call to undefined method Illuminate\Database\Query\Builder::setNull() in /vagrant/door/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2443
Stack trace:
#0 /vagrant/door/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(1239): Illuminate\Database\Query\Builder->__call('setNull', Array)
#1 [internal function]: Illuminate\Database\Eloquent\Builder->__call('setNull', Array)
#2 /vagrant/door/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/Relation.php(340): call_user_func_array(Array, Array)
#3 /vagrant/door/app/Model/Product.php(44): Illuminate\Database\Eloquent\Relations\Relation->__call('setNull', Array)
#4 /vagrant/door/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(348): App\Model\Product::App\Model\{closure}(Object(App\Model\Product))
#5 /vagrant/door/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(199): Illuminate\Events\Dispatcher->Illuminate\Events\{closure}('eloquent.delete...', Array)
#6 /vagrant/door/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(172): Illuminate\Events\Dispatcher->dispatch('eloquent.delete...', Array, false)
#7 /vagrant/door/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasEvents.php(148): Illuminate\Events\Dispatcher->fire('eloquent.delete...', Object(App\Model\Product))
#8 /vagrant/door/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(748): Illuminate\Database\Eloquent\Model->fireModelEvent('deleted', false)
#9 /vagrant/door/app/Http/Controllers/ProductController.php(80): Illuminate\Database\Eloquent\Model->delete()
#10 [internal function]: App\Http\Controllers\ProductController->destroy(Object(App\Http\Requests\ProductRequest), '1')

在您的项目模型中定义一个自定义方法,例如

 public function setNull() 
{
 $this->field_names= NULL; 
$this->save(); 
}

然后在引导函数中你调用这个方法就像

$product->projects()->setNull(); 

P. S- 抱歉,我在用手机

查看dissociate()方法,这将重置关系的外键和对象上的关系。

基本上你想要这样的东西:

static::deleted(function($product)
{
    // remove relation
    $product->projects()->each(function($project) {
        $project->product()->dissociate();
        $project->save();
    });
});