Skip to content

Trying to load non-existing relationships on deserialisation of an object with polymorphic children #26126

Closed
@jsphpl

Description

@jsphpl
  • Laravel Version: 5.7.7
  • PHP Version: 7.2
  • Database Driver & Version: Postgres

Description:

Relationships that were loaded on a model before serialisation are restored during deserialisation, eg. when using a model in a queued event or job. During deserialisation, an error occurs if a polymorphic relationship was loaded on the model, where one of the polymorphic types has in turn a child relationship loaded that does not exist on one of the other polymorphic types. The issue occurs when the polymorphic child that has the relationship is first in the relationship and the nested relationship is loaded during serialisation.

I assume this method in Eloquent\Collection is part of the issue by picking the the first item in the collection to determine which child relationships exist:

    /**
     * Get the relationships of the entities being queued.
     *
     * @return array
     */
    public function getQueueableRelations()
    {
        return $this->isNotEmpty() ? $this->first()->getQueueableRelations() : [];
    }

Steps To Reproduce:

1. Have the following model tree:

class Parent extends Model
{
    public function children()
    {
        return $this->morphTo();
    }
}

class ChildTypeOne extends Model
{
    public function parent()
    {
        return $this->morphMany(Parent::class, 'parentable');
    }

    public function nestedRelationship()
    {
        // Note: This relationship does not exist on ChildTypeTwo
        $this->hasMany(AnyOtherModel::class);
    }
}

class ChildTypeTwo extends Model
{
    public function parent()
    {
        return $this->morphMany(Parent::class, 'parentable');
    }
}

2. Create some instances

3. ->load('children') on a Parent instance, ensuring that the first loaded item is a ChildTypeOne

4. ->load('nestedRelationship') on the first of the ChildTypeOne instanced loaded on the parent

5. Serialize the Parent instance, eg. by setting it as a property of a queued job or event

6. Deserialize it by handling the job.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions