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

superbiche's avatar

Nested many-to-many

Hey there,

First I apologize if this question was already asked but it seems this is beyond my Googling skills :)

I'm maintaining a marketplace built with Laravel 5.4 (for the API part).

I have 3 related models:

  • Helper (someone offering its services on our platform)
  • Service (a service, potentially offered by a Helper)
  • Option (the new class, an option for the service, eg. for the Babysitting service, an option could be "has_own_transport" so we know the Helper has its own car (and driving licence indeed).

Here are the relevant parts of the models (BaseModel just extends Eloquent's model with convenient methods):

Helper model:


class Helper extends BaseModel
{
    protected $fillable = [
        'user_id',
        'siret',
        'sap',
        'company_name',
        'active',
     ];

    public function services(): BelongsToMany
    {
        return $this->belongsToMany('App\Models\Service',
            'helper_services')
            ->withPivot(['description', 'level']);
    }

Service model:


class Service extends BaseModel
{

    protected $fillable = [
        'name',
        'text',
    ];

    public function helpers(): BelongsToMany
    {
        return $this->belongsToMany('App\Models\Helper', 'helper_services');
    }

    public function options(): HasMany
    {
        return $this->hasMany(Option::class, 'service_id');
    }

}

Option model:


class Option extends BaseModel
{
    protected $table = 'service_options';

    protected $fillable = [
        'service_id',
        'name',
        'searchable',
    ];

    public function services(): BelongsTo
    {
        return $this->belongsTo(Service::class, 'service_id');
    }
}

And the relevant pivot tables, without the foreigns:


##
# The pivot between helpers <> services
##
CREATE TABLE `helper_services` (
  `helper_id` int(10) unsigned NOT NULL,
  `service_id` int(10) unsigned NOT NULL,
  `description` text COLLATE utf8_unicode_ci NOT NULL,
  `level` int(11) DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


##
# The pivot between helpers <> services
##
CREATE TABLE `helper_service_options` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `helper_id` int(10) unsigned NOT NULL,
  `service_option_id` int(10) unsigned NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  `deleted_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

So far so good as:

  • In my services endpoint, I can use the Services standalone, so the user can search a Helper based on the services he offers
  • In my helpers endpoint, I can use the Helper's services relationship so I have all the services he offers.

But now, I also need the same thing for Options:

  • In my services endpoint (standalone), I want each Service to expose its available Options
  • In my helpers endpoint, I'd like to have, for each helper service, the options the helper has checked (from helper_service_options table).

For the original relation (helper->services) it's working perfectly, but now I'm stuck at creating this nested, many-to-many relationship.

Has someone an idea on how to do this?

Thanks in advance :)

0 likes
0 replies

Please or to participate in this conversation.