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

JohnBeales's avatar

Three Way Relationship or Relationship with a Relationship?

I'm puzzling over how to set up this relationship in Laravel, (I'm converting a legacy app):

I have Repair Shops, which provide different types of repairs, on different brands of vehicles.

For example, Shop A might repair Brakes but not Exhaust Systems for Ford vehicles. Shops are required to say what services they provide, (Exhaust repair), but adding a brand is optional. I have Shop, Service, and Brand tables in the DB. Shop and Service have a belongsToMany relationship using the provides_service pivot table. In the legacy system I have a 3-way pivot table to specify what Services can be done to each Brand in each Shop.

Laravel doesn't seem to do 3-way relationships well, (or does it? If so, point me there!). So, I feel like it would make sense to create a belongsToMany between the provides_service relation and the Brand. So, is there a way to set up a relationship between a Model and another Relationship in Laravel, or do I have to create a ProvidesService model? Creating a ProvidesService model seems wasteful, but I'm not sure what else to do here.

0 likes
7 replies
shez1983's avatar

i am a bit lost. i think there are two things i get from your post

  1. shops can do x many services
  2. shops can only do some services on a particular brand

i would go with your suggestion of creating a providesService Model unfortunately.

1 like
jlrdw's avatar

I'd find an all service shop.

JohnBeales's avatar

@ROERJO - I looked at hasManyThrough, and it doesn't seem to quite work. If I take the "wasteful" approach of making a ProvidesService model then I'll be able to use hasManyThrough to get the brands that a Shop can service, which may be useful.

JohnBeales's avatar

@SHEZ1983 - It's more like:

  1. shops can do x services
  2. Some services are available for only some brands, but not others, (still on the Cars example, a garage needs computer software from Ford to turn off your Ford's Check Engine light, so they might offer "Turn off Check Engine Light" for Ford, but not Chevy).

Someone in Slack pointed me at the fact that when making the "wasteful" providesService model I would probably be extending a Illuminate\Database\Eloquent\Relations\Pivot object, which I'm guessing is used behind the scenes anyway, so it's less wasteful than I had thought. I'm going to give that a shot and see how it works.

JohnBeales's avatar

@ROERJO - That's what I'm going to so.

I looked at the Pivot model source, and it just inherits from the main Model with an extra Pivot trait, but I'm guessing that's what's used behind the scenes anyway, so by defining my own that inherits from that it shouldn't be much of a performance hit.

1 like

Please or to participate in this conversation.