framework: Pivot::original contains incorrect data
- Laravel Version: 5.8.19
- PHP Version: 7.1.13
- Database Driver & Version: MySQL 5.5.5-10.3.8-MariaDB
Description:
After creating a Model, the original
array is empty and the attributes
array contains all the attributes used to create the Model and optionally the auto-incrementing id.
Same is true when a Pivot is created via FooPivot::create()
.
However after creating a Pivot using the $model->relationship()->attach($id, $attributes)
method, the original
array contains all of the foreign keys and the pivot attributes passed to the attach()
call.
Steps To Reproduce:
Run:
php artisan make:model Invoice -m
php artisan make:model Product -m
php artisan make:model InvoiceProduct -m -p
Fill in the migrations:
create_invoices_table
:
Schema::create('invoices', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('number');
$table->timestamps();
});
create_invoice_product_table
:
Schema::create('invoice_product', function (Blueprint $table) {
$table->unsignedInteger('invoice_id');
$table->unsignedInteger('product_id');
$table->unsignedInteger('count');
});
You can leave the create_products_table
migration unchanged.
Update the models:
App\Invoice
:
class Invoice extends Model
{
protected $guarded = [];
public static function boot()
{
parent::boot();
static::created(function (Model $model) {
dump([
'attributes' => $model->getAttributes(),
'original' => $model->getOriginal(),
'dirty' => $model->getDirty(),
]);
});
}
public function products()
{
return $this->belongsToMany(Product::class)
->using(InvoiceProduct::class)
->withPivot('count');
}
}
App\InvoiceProduct
:
class InvoiceProduct extends Pivot
{
public static function boot()
{
parent::boot();
static::created(function (Model $model) {
dump([
'attributes' => $model->getAttributes(),
'original' => $model->getOriginal(),
'dirty' => $model->getDirty(),
]);
});
}
}
You can leave the App\Product
model unchanged.
Run:
php artisan migrate
In the Tinker run:
$invoice = \App\Invoice::create(['number' => '123']);
You should see the correct attributes
, original
and dirty
arrays:
array:3 [
"attributes" => array:4 [
"number" => "123"
"updated_at" => "2019-06-01 10:08:57"
"created_at" => "2019-06-01 10:08:57"
"id" => 1
]
"original" => []
"dirty" => array:4 [
"number" => "123"
"updated_at" => "2019-06-01 10:08:57"
"created_at" => "2019-06-01 10:08:57"
"id" => 1
]
]
Then, again in the Tinker, run:
$product = \App\Product::create();
$invoice->products()->attach($product, ['count' => 2]);
You should see the following output:
array:3 [
"attributes" => array:3 [
"product_id" => 1
"invoice_id" => 1
"count" => 2
]
"original" => array:3 [
"product_id" => 1
"invoice_id" => 1
"count" => 2
]
"dirty" => []
]
Clearly the pivot has just been created, therefore the original
array should be empty and the dirty
array should contain at least the count
field.
One side note: If you add auto-incrementing id to the pivot table and enable it with
public $incrementing = true;
you’re gonna see the id
field in the dirty
array but not in the original
array.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 1
- Comments: 16 (16 by maintainers)
Fixed in next 6.x / 7.x patch release.