Framework: [5.3] withTrashed() breaks when used with eager loading

Created on 23 Feb 2017  路  9Comments  路  Source: laravel/framework

  • Laravel Version: 5.3.30
  • PHP Version: 5.6.15
  • Database Driver & Version: mysql 5.6.31

Description:

I have a Polymorphic relation on a model

    public function reviewable()
    {
        return $this->morphTo()->withTrashed();
    }

If i do not eager load the reviewable() Every thing works fine, but if i eager load the relation a BadMethodCallException is thrown

BadMethodCallException in Builder.php line 2450:

Call to undefined method Illuminate\Database\Query\Builder::withTrashed()

By the way i'm using lazy eager loading with the load() method.

Most helpful comment

@uruloke The solution that i used to temporarly solve my problem is that i add a withTrashed local scope to the classes that are used in the morph relationship but they do not use the SoftDeletes trait

public function scopeWithTrashed($query)
{
    return $query;
}

All 9 comments

Does this happen in 5.4 as well?

I didn't test it on 5.4

@shadoWalker89 , The model you are trying to morph to, does it have softDeletes trait on it?

I did some testing and the error seems to be happening when using withTrashed when the model is not using softDeletes. This only happens when using lazy eager loading load() method, it did not happen for me when I tried with other methods.

@srmklive Yes it happens on 5.4 as well.

@uruloke Can you share a working example that demonstrates this issue?

@srmklive Added the following test to DatabaseEloquentSoftDeletesIntegrationTestEagerLoaded.php

public function testMorphToWithTrashedRelationshipLazyEagerLoadedOnNonSoftDeletedUser()
{
    $this->createUsers();

    $abigail = TestUserWithoutSoftDelete::where('email', '[email protected]')->first();
    $post1 = $abigail->posts()->create(['title' => 'First Title']);
    $post1->comments()->create([
        'body' => 'Comment Body',
        'owner_type' => TestUserWithoutSoftDelete::class,
        'owner_id' => $abigail->id,
    ]);

    $comment = TestCommentWithTrashedOwner::first();

    $comment->load('owner');

    $this->assertEquals($abigail->id, $comment->owner->id);
}

And with this simple model.

class TestCommentWithTrashedOwner extends Eloquent
{
    protected $table = 'comments';
    protected $guarded = [];

    public function owner()
    {
        return $this->morphTo()->withTrashed();
    }
}

Here is a gist of the whole test file with my test added https://gist.github.com/uruloke/da9165c7263b305db34e704b6dbbfca3

@uruloke From the models that i morphing to only one model uses SoftDeletes

Also i can confirm when eager loading the relation morphTo (relation in my case reviewable) while it's related only to models that uses soft deletes it work just fine.
If i add models that doesn't use the SoftDeletes trait, the problem occurs.

I guess the problem is because the withTrashed() scope is added as a macro only on models that uses the SoftDeletes trait

@shadoWalker89 same conclusion I made.
Altough I am not sure if this is intended behaviour or not.

@uruloke The solution that i used to temporarly solve my problem is that i add a withTrashed local scope to the classes that are used in the morph relationship but they do not use the SoftDeletes trait

public function scopeWithTrashed($query)
{
    return $query;
}
Was this page helpful?
0 / 5 - 0 ratings