guybrush_threepwood's avatar

One to Many relationship with a polymorphic twist

Hello everyone,

I'm really racking my brains trying to get this to work with no avail. None of the relationships described in the Laravel docs seem to work in my case and experimentation isn't going well.

I have the following models: Invoice, Order, Purchase and Storage. An Invoice may have many Orders, Purchases or Storages associated. But each Order, Purchase or Storage may belong to one Invoice only.

It seems to me that I should be using some sort of polymorphic pivot table:

        Schema::create('items', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('invoice_id');
            $table->string('itemable_type');
            $table->unsignedBigInteger('itemable_id');
            $table->timestamps();

            $table->unique(['itemable_type', 'itemable_id']);

            $table->foreign('invoice_id')
                ->references('id')
                ->on('invoices')
                ->onDelete('cascade');
        });

But I have no idea how to set up the relationships. Any help would be really appreciated.

0 likes
3 replies
jlrdw's avatar

As far as invoice type maybe a simple added field of type would work. I don't usually like enum, but that could work too. To me a varchar type with a drop down selection is easier.

Just suggestion.

1 like
guybrush_threepwood's avatar

Hi @jlrdw, thank you for your reply.

In this case each Invoice can have multiple "items" associated and types can be combined.

For example, Invoice 1 may have:

  • Order 1
  • Order 2
  • Purchase 1
  • Storage 1

That's why I thought about polymorphism. I wouldn't want to create a pivot table for each item type since new types may appear in the future.

jeffallen's avatar

@guybrush_threepwood maybe a related table of types and on the invoice have the type next to the line number:

TYPE    Product   Description   more...
1           Order 1
1           Order 2
2          Storage

Something like that.

Please or to participate in this conversation.