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 1:
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()
Solution 2:
You could define your scope like an anonymous global scope
class Basket extends Model
{
protected static function booted()
{
static::addGlobalScope('withProduct', function (Builder $builder) {
$builder->with('product');
});
}
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');
}
}
}
Or use the $with
property.
class Basket extends Model
{
/**
* The relations to eager load on every query.
*
* @var array
*/
protected $with = ['product'];
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');
}
}
}