2

I can't access pivot model's id attribute. I have one pivot model PivotModel and two models that are connected through this pivot model

ModelA class:

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

ModelB class:

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

PivotModel:

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

Pivot table migration file

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

I assume this should work. This is from the official documentation for Laravel 5.8

Custom Pivot Models And Incrementing IDs If you have defined a many-to-many relationship that uses a custom pivot model, and that pivot model has an auto-incrementing primary key, you should ensure your custom pivot model class defines an incrementing property that is set to true.

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

I can only access the prop_1 and prop_2 properties but not the id property.

The id is null

dump($model->id); 

and the toArray() only shows other props but not the id

dump($model->toArray());
dparoli
  • 8,891
  • 1
  • 30
  • 38
Sašo Kovačič
  • 891
  • 1
  • 9
  • 21

1 Answers1

3

I found a temporary solution. If you know how to do it better please suggest.

As mentionied, the id property is accessible in the created() method so you can easily get it using $model->id.

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

The problem is in the updated() method where the $model instance is filled with properties other than id. See the method updateExistingPivotUsingCustomClass inside of Illuminate\Database\Eloquent\Relations\Concerns\InteractsWithPivotTable

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 ...
    }
});
Sašo Kovačič
  • 891
  • 1
  • 9
  • 21
  • 1
    This works great, but for anyone else that finds this I had to modify the query a bit, using `getForeignKey()` and `getRelatedKey()` instead of just `foreignKey` and `relatedKey` – ams Dec 17 '19 at 15:40