Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Adcade's avatar

Eloquent OneToMany relationship with multiple possible columns

I have the following tables:

  • categories: id, name
  • products: sku, name, category1, category2, category3

Where category 1, 2 and 3 are the IDs of different elements in categories table.

I need to define a relationship where a product can have the category id in ANY of the three columns. Right now my models are:

class Category extends Model
{
    protected $fillable = [
        'id',
        'name',
    ];

    public function products()
    {
        return Product::where('category1', $this->id)->orWhere('category2', $this->id)->orWhere('category3', $this->id)->get();
    }
}
class Product extends Model
{
    protected $primaryKey = 'sku';

    public function category1()
    {
        return $this->belongsTo(Category::class, 'category1');
    }

    public function category2()
    {
        return $this->belongsTo(Category::class, 'category2');
    }

    public function category3()
    {
        return $this->belongsTo(Category::class, 'category3');
    }
}

But anytime I try to get the products that belong in a category (1, 2 or 3), I get the error

LogicException with message 'App/Category::products must return a relationship instance.'

How should I define the products() function?

0 likes
1 reply
Snapey's avatar
Snapey
Best Answer
Level 122

Eloquent is not really going to help you here.

What you should do is have a category_product table with category_id and product_id columns, then define belongsToMany relationships in both models.

You can then have 1,2 3 (or more) categories for any product and you don't need to have any special functions to get all products in a category or all categories for a product.

https://laravel.com/docs/5.8/eloquent-relationships#many-to-many

1 like

Please or to participate in this conversation.