RonnyKnoxville
RonnyKnoxville

Reputation: 6394

Eloquent hasOneThrough withTrashed

I have a set of product models with the following relationships:

OrderProduct -> AccountProduct -> Product

The OrderProduct model belongsTo an AccountProduct and has a hasOneThrough relationship to a product. These relationships work fine, until Im in a situation where the accountProduct and the Product have been soft deleted. I can still retrieve the relationship through chaining, but the hasOneThrough fails to work in this scenario.

public function accountProduct(): BelongsTo
{
    return $this->belongsTo(AccountProduct::class)
        ->withTrashed();
}

public function product(): HasOneThrough
{
    return $this->hasOneThrough(
        Product::class,
        AccountProduct::class,
        'id',
        'id',
        'account_product_id',
        'product_id'
    )->withTrashed();
}

Output:

echo $orderProduct->accountProduct->product->id

"1"


echo $orderProduct->product

"Trying to get property ID of a non object"

Is there a code change I can make to get Eloquent to return a HasOneThrough relationship when both the accountProduct and orderProduct are soft deleted?

Upvotes: 1

Views: 943

Answers (2)

Alexey Savchuk
Alexey Savchuk

Reputation: 1128

return $this->hasOneThrough(...)
            ->withTrashed()
            ->withTrashedParents();

Upvotes: 3

Jonas Staudenmeir
Jonas Staudenmeir

Reputation: 25906

Laravel has no native support for this.

I've created a package for it: https://github.com/staudenmeir/eloquent-has-many-deep

class OrderProduct extends Model
{
    use \Staudenmeir\EloquentHasManyDeep\HasRelationships;

    public function product(): HasOneThrough
    {
        return $this->hasOneDeep(
            Product::class,
            [AccountProduct::class],
            ['id', 'id'],
            ['account_product_id', 'product_id']
        )->withTrashed()
        ->withTrashed('account_products.deleted_at');
    }
}

Upvotes: 0

Related Questions