0

I'm trying to use two different Category model to the same items table.

I'v got 3 models

SystemCategory

Schema::create('system_categories', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('name');
        $table->timestamps();
    });

UserCategory

Schema::create('user_categories', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('name');
        $table->integer('user_id');
        $table->timestamps();
    });

Item

Schema::create('items', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('name');
        $table->integer('categoryable_id');
        $table->string('categoryable_type');
        $table->timestamps();
    });

Item category could be either from system_categories or user_categories table

I saw some Polymorphic relations but its about how two different models can belongs to one category, not about how model can belongs to two different category models

Thanks.

SirMissAlot
  • 120
  • 2
  • 11
  • How many `SystemCategory`/`UserCategory` can an `Item` have? – Rwd Jun 07 '20 at 10:32
  • one. only one type of one of them @Rwd – SirMissAlot Jun 07 '20 at 10:46
  • You can definitely use a polymorphic relationship here. `Item` would have the `morphTo` relationship and the category models would have a `morphMany` relationship. – Rwd Jun 07 '20 at 11:14
  • I'm having some troubles, can you elaborate please ? added scheme to question @Rwd – SirMissAlot Jun 07 '20 at 11:41
  • The problem you are facing is called `polymorphic associations`. Please check here https://stackoverflow.com/a/441111/2188922 - it suggest that instead of keeping one type column + a foreign key(to multiple tables) - it suggest to use two foreign key columns(nullable) to two different tables. If you want to still implement your way; please check this section https://laravel.com/docs/7.x/eloquent-relationships#custom-polymorphic-types – Ersoy Jun 07 '20 at 12:01
  • @Ersoy OP is using Laravel which uses polymorphic relationships out of the box – ColinMD Jun 07 '20 at 12:31
  • @ColinMD if you keep reading you will see "if you want to still implement..." part which directs to laravel website that shows i am aware of it. – Ersoy Jun 07 '20 at 12:45
  • 1
    @Ersoy apologies I stopped reading when you were recommending doing something different than what the framework does out of the box. – ColinMD Jun 07 '20 at 12:49

1 Answers1

2

It can be done, first thing your schema looks ok but you want to set catagoryable_id to a bigInteger to match the id columns of the 2 category tables.

Then you would set your models up

class Item extends Model
{
    public function categoryable() 
    {
        return $this->morphTo();
    }
}

class SystemCategory extends Model
{
    public function items()
    {
        return $this->morphMany('App\Item', 'categoryable');
    }
}

class UserCategory extends Model
{
    public function items()
    {
        return $this->morphMany('App\Item', 'categoryable');
    }
}

Obviously this is presuming your models are in the App namespace

ColinMD
  • 952
  • 6
  • 14
  • Thank you, it works !! just changed to $this->morphOne('App\Item', 'categoryable'); – SirMissAlot Jun 07 '20 at 12:36
  • You can use morphOne but if item1 and item2 both have the same system category then calling item(s) will only return one of those item records. – ColinMD Jun 07 '20 at 12:40
  • Attach is only used in Many to Many where you have a pivot table. Instead you would use the save method. $Item->categoryable()->save($Category); – ColinMD Jun 07 '20 at 13:01
  • Yes I found the answer for that : $Item->categoryable()->associate($Category); – SirMissAlot Jun 07 '20 at 13:05