首页 > 解决方案 > 无法在 Laravel 的 static::saved() 方法中访问数据透视模型的 id 属性

问题描述

我无法访问数据透视模型的 id 属性。我有一个枢轴模型 PivotModel 和两个通过此枢轴模型连接的模型

模型A类:

public function modelB()
{
    return $this->belongsToMany(ModelB::class, 'model_a_model_b', 'model_a_id', 'model_b_id')
        ->using(PivotModel::class)
        ->withPivot('id', 'prop_1', 'prop_2');
}

模型B类:

public function modelA()
{
    return $this->belongsToMany(ModelA::class, 'model_a_model_b', 'model_b_id', 'model_a_id')
        ->using(PivotModel::class)
        ->withPivot('id', 'prop_1', 'prop_2');
}

枢轴模型:

use Illuminate\Database\Eloquent\Relations\Pivot;

class PivotModel extends Pivot
{
    public $incrementing = true;

    public static function boot() {

        parent::boot();

        static::saved(function ($model) {
            dump($model->id);
            dump($model->toArray());
        });
    }
}

数据透视表迁移文件

Schema::create('model_a_model_b', function (Blueprint $table) {
    $table->increments('id');
    $table->unsignedInteger('model_a_id');
    $table->unsignedInteger('model_b_id');
    $table->string('prop_1');
    $table->string('prop_2');

    $table->unique(['model_a_id', 'model_b_id'], 'model_a_id_model_b_id');

    $table->foreign('model_a_id')
        ->references('id')->on('model_a')
        ->onDelete('cascade')
        ;

    $table->foreign('model_b_id')
        ->references('id')->on('model_b')
        ->onDelete('cascade')
        ;

    $table->timestamps();
});

我认为这应该有效。这是来自 Laravel 5.8 的官方文档

自定义枢轴模型和递增 ID 如果您定义了使用自定义枢轴模型的多对多关系,并且该枢轴模型具有自动递增的主键,则应确保自定义枢轴模型类定义的递增属性为设置为真。

/**
 * Indicates if the IDs are auto-incrementing.
 *
 * @var bool
 */
public $incrementing = true;

我只能访问 prop_1 和 prop_2 属性,但不能访问 id 属性。

id 为空

dump($model->id); 

并且 toArray() 只显示其他道具但不显示 id

dump($model->toArray());

标签: laravellaravel-5eloquentpivotlaravel-5.8

解决方案


我找到了一个临时解决方案。如果您知道如何做得更好,请提出建议。

如前所述,id 属性可在 created() 方法中访问,因此您可以使用 $model->id 轻松获取它。

static::created(function ($model) {
    dump($model->id); 
});

问题出在 updated() 方法中,其中 $model 实例填充了 id 以外的属性。请参阅 Illuminate\Database\Eloquent\Relations\Concerns\InteractsWithPivotTable 中的方法 updateExistingPivotUsingCustomClass

static::updated(function($model) {
    // If the model is of type Pivot we have to store it into a different variable or overwrite it. If we need dirty props we first need to store them to separate variable before overwriting the $model variable

    $dirtyProps = $model->getDirty();

    if($model instanceof Pivot) {

        $model = get_class($model)
            ::where($model->foreignKey, $model->{$model->foreignKey})
            ->where($model->relatedKey, $model->{$model->relatedKey})
            ->firstOrFail();

        // Use the model
        $model->id ...
    }
});

推荐阅读