staudenmeir / belongs-to-through

Laravel Eloquent BelongsToThrough relationships
MIT License
1.17k stars 91 forks source link

withTrashed doesn't work for destination model #51

Closed ggolda closed 4 years ago

ggolda commented 4 years ago

In my model I have relation like that:

return $this->belongsToThrough(
    Project::class,
    Asset::class
)->withTrashed();

But withTrashed doesn't work with Project model that has a SoftDeletes trait. As I can see from a query log, deleted_at is null is still added to a query.

staudenmeir commented 4 years ago

Please share the executed SQL.

ggolda commented 4 years ago

So for example above, both Project and Asset can be soft deleted. If I provide withTrashed with default values, here is the generated SQL query:

select `projects`.* from `projects` inner join `assets` on `assets`.`project_id` = `projects`.`id` where `assets`.`deleted_at` is null and `assets`.`id` = ? limit 1

If I specify a parameter for withTrashed call, the code looks like:

return $this->belongsToThrough(
        Project::class,
        Asset::class
)->withTrashed('assets.deleted_at')

and SQL query:

select `projects`.* from `projects` inner join `assets` on `assets`.`project_id` = `projects`.`id` where `assets`.`id` = ? and `projects`.`deleted_at` is null limit 1

If I provide both assets and projects parameters to a withTrashed function call like that:

return $this->belongsToThrough(
        Project::class,
        Asset::class
)->withTrashed(['assets.deleted_at', 'projects.deleted_at']);

query looks identical to a version where only assets parameter is specified:

select `projects`.* from `projects` inner join `assets` on `assets`.`project_id` = `projects`.`id` where `assets`.`id` = ? and `projects`.`deleted_at` is null limit 1
staudenmeir commented 4 years ago

You need two withTrashed() calls:

return $is->belongsToThrough(
        Project::class,
        Asset::class
)->withTrashed()->withTrashed('assets.deleted_at');

->withTrashed() is the native Laravel call for the related model (Project); ->withTrashed('assets.deleted_at') is the package's call for intermediate tables (Asset).

ggolda commented 4 years ago

Thanks, I will try it out!