Skip to content

[5.8] Sync method return wrong updated record and event with Pivot class #28150

Closed
@link08

Description

@link08
  • Laravel Version: 5.8.10
  • PHP Version: 7.2.16
  • Database Driver & Version: mysql 5.7

Description:

After the update from Laravel 5.7 to Laravel 5.8 the sync() method with pivot class doesn't return the correct values.

Problem 1

If I try to read the response from the ->sync() method, inside the 'updated' value there are all the values, even if there wasn't any change.

Problem 2

I updated to Laravel 5.8 to use the Observer with the pivot class but the updated event is triggered every time and I can't get the original value of a pivot attribute with the method ->getOriginal()

Steps To Reproduce:

Models:

class Person extends Model
{
    //
}

class Business extends Model
{
    public function people()
    {
        return $this->belongsToMany(Person::class, 'business_person_role')
            ->using(BusinessPersonRole::class)
            ->withPivot([
                'role_id',
            ])
            ->withTimestamps();
    }
}

class Role extends Model
{
    //
}

class BusinessPersonRole extends Pivot
{
    protected $table = 'business_person_role';
}

Sample code:

    $person1 = factory(Person::class)->create(); // Id: 1
    $person2 = factory(Person::class)->create(); // Id: 2
    $person3 = factory(Person::class)->create(); // Id: 3
    $person4 = factory(Person::class)->create(); // Id: 4

    $business1 = factory(Business::class)->create(); // Id:1

    $role1 = factory(Role::class)->create(); // Id: 1
    $role2 = factory(Role::class)->create(); // Id: 2

    $business1->people()->attach([
        $person1->id => ['role_id' => $role1->id],
        $person2->id => ['role_id' => $role1->id],
        $person3->id => ['role_id' => $role1->id],
    ]);

    var_dump($business1->people()->get()->pluck('pivot.role_id', 'id')->toArray());
    /*
     * array (size=3)
     * 1 => int 1
     * 2 => int 1
     * 3 => int 1
     */

    $changes = $business1->people()->sync([
        $person1->id => ['role_id' => $role2->id],
        $person3->id => ['role_id' => $role1->id],
        $person4->id => ['role_id' => $role1->id],
    ]);

    var_dump($business1->people()->get()->pluck('pivot.role_id', 'id')->toArray());
    /*
     * array (size=3)
     * 1 => int 2
     * 3 => int 1
     * 4 => int 1
     */

    var_dump($changes);
    /*
     * array (size=3)
     *   'attached' => 
     *     array (size=1)
     *       0 => int 4
     *   'detached' => 
     *     array (size=1)
     *       1 => int 2
     *   'updated' => 
     *     array (size=2)
     *       0 => int 1
     *       1 => int 3    <======= This value is wrong
     */

with Laravel 5.7 the last var_dump return:

    var_dump($changes);
    /*
     * array (size=3)
     *   'attached' => 
     *     array (size=1)
     *       0 => int 4
     *   'detached' => 
     *     array (size=1)
     *       1 => int 2
     *   'updated' => 
     *     array (size=1)
     *       0 => int 1
     */

Observer:

// Observer registered inside the Service Provider
BusinessPersonRole::observe(BusinessPersonRoleObserver::class);

// BusinessPersonRoleObserver.php
class BusinessPersonRoleObserver
{
    public function updated(BusinessPersonRole $businessPersonRole)
    {
        var_dump('------');
        var_dump($businessPersonRole->person_id);
        var_dump($businessPersonRole->business_id);
        var_dump($businessPersonRole->role_id);
        var_dump($businessPersonRole->getOriginal('role_id'));

        /*
         *  === > Correct record <===
         * string '------' (length=6)
         * int 1
         * int 1
         * int 2
         * null
         *
         * === > Wrong record <===
         * string '------' (length=6)
         * int 3
         * int 1
         * int 1
         * null
         */
    }
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions