Search code examples
laraveleloquenteager-loading

is there a way to access model attributes while using with method


hey guys i have a problem. im trying to eagerload my basket items by defining a scope:

public function apply(Builder $builder, Model $model)
{
    $builder->with(['product']);
}

and my product relation inside basket model is like below:

public function product()
{
    if ($this->used_product_id) {
        return $this->belongsTo(UsedProduct::class, 'used_product_id', 'id');
    } else {
        return $this->belongsTo(Product::class, 'product_id', 'id');
    }
}

but the problem is when using with() $this->used_product_id returns null and i cant get access to my current model attributes. do you have any solution?


Solution

  • I would try something like this:

    class Basket extends Model
    {
    
        public function newProduct()
        {
            return $this->belongsTo(Product::class, 'product_id', 'id');
        }
    
        public function usedProduct()
        {
            return $this->belongsTo(UsedProduct::class, 'used_product_id', 'id');
        }
    
        public function product()
        {
            return $this->usedProduct ?? $this->newProduct ?? null;
        }
    
    }
    

    To make sure that the products are eager loaded, you'd have to load it with both products, like

    Basket::with(['newProduct','usedProduct'])->get()