mskhoshnazar's avatar

Belongs to many through

I wonder why this is not a part of laravel.

Let's say we have projects and categories that belongToMany each other. That's easy. Then we have campaigns that belong to one project, and we want them to have the same categories as their parent project. How do we do that?

campaigns:

  • id
  • title
  • project id

projects:

  • id
  • title

category_project:

  • category_id
  • project_id

categories:

  • id
  • title
0 likes
6 replies
tykus's avatar

Check out this package, if I understand what you need correctly, then this should work.

1 like
rodrigo.pedra's avatar
Level 56

If I understand it well I guess you could use the same pivot table to achieve what you described

Models

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Project extends Model
{
    use HasFactory;

    public function campaigns()
    {
        return $this->hasMany(Campaign::class);
    }

    public function categories()
    {
        return $this->belongsToMany(Category::class);
    }
}
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    use HasFactory;

    public function campaigns()
    {
        return $this->belongsToMany(Campaign::class, 'category_project', null, 'project_id', null, 'project_id');
    }

    public function projects()
    {
        return $this->belongsToMany(Project::class);
    }
}

Note how the related keys on the belongsToMany relation are defined

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Campaign extends Model
{
    use HasFactory;

    public function categories()
    {
        return $this->belongsToMany(Category::class, 'category_project', 'project_id', null, 'project_id');
    }

    public function project()
    {
        return $this->belongsTo(Project::class);
    }
}

Note how the related keys on the belongsToMany relation are defined

Testing

<?php

// ./routes/web.php

use Illuminate\Support\Facades\Route;


Route::get('/', function () {
    return [
        'projects' => \App\Models\Project::with(['campaigns.categories'])->get(),
        'campaings' => \App\Models\Campaign::with(['project', 'categories'])->get(),
        'categories' => \App\Models\Category::with(['campaigns.project', 'projects.campaigns'])->get(),
    ];
});
4 likes
CItyTrader's avatar

@rodrigo.pedra I know I'm super late. I just came across this and wow, it really works. Please can you explain how and why this works, I'm quite curious

ebeneoyen's avatar

Please I have a different scenario and I wish I can get help in this forum. My database is as such

teams:

id

team

positions:

id

position

team_id

user_postions:

user_id

position_id

users:

id

name

Is it possible for me to get the teams a user belongs to through their positions? Thanks for your help

Please or to participate in this conversation.