Ad

2 ManyToMany Relationship + 1 Param In Laravel Eloquent

- 1 answer

I have 2 tables A and B.

I make a many to many Relationship with a pivot table called A_B

Now I need to make other ManyToMany Relationship between A_B and User ( U )

So I have another table A_B_U

Now, What I need and can't do it, is writing a relationship from A to A_B_U.

I set U to a vale, so A_B -> A_B_U is now a belongsTo Relationship, I should be able to access it easily, but I can't write it, I can write the first relationship, but then, I can't write the second one.

I don't know neither how to pass a param in ManyToMany Rel.

In fact, it shoud be a belongsTo, not ManyToMany so I'm a bit lost in all that....

Any Idea how to do it?

Ad

Answer

What it looks like

            category_tournament_user
                   /        \
    category_tournament    users
        /       \
tournaments   categories

Migrations

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

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

Schema::create('category_tournament', function(Blueprint $table) {
    $table->increments('id');
    $table->integer('category_id');
    $table->integer('tournament_id');
    $table->timestamps();
});

Schema::create('category_tournament_user', function(Blueprint $table) {
    $table->integer('category_tournament_id');
    $table->integer('user_id');
});

Models

class Tournament extends Model
{
    public function categories()
    {
        return $this->belongsToMany(Category::class);
    }

    public function categoryTournaments()
    {
        return $this->hasMany(CategoryTournament::class);
    }
}

class Category extends Model
{
    public function tournaments()
    {
        return $this->belongsToMany(Tournament::class);
    }

    public function categoryTournament()
    {
        return $this->hasMany(CategoryTournament::class);
    }
}

class CategoryTournament extends Model
{
    protected $table = 'category_tournament';

    public function category()
    {
        return $this->belongsTo(Category::class);
    }

    public function tournament()
    {
        return $this->belongsTo(Tournament::class);
    }

    public function users()
    {
        return $this->belongsToMany(User::class, 'category_tournament_user');
    }
}

class User extends Authenticatable
{
    public function categoryTournaments()
    {
        return $this->belongsToMany(CategoryTournament::class, 'category_tournament_user');
    }
}

Get all users of a tournament

$tournament = App\Tournament::with('categoryTournaments.users')->find(1);

foreach($tournament->categoryTournaments as $categoryTournament) {

    // To get the category of the tournament, this will return an App\Category
    $category = $categoryTournament->category;

    // If you have a name column on your categories table...
    $categoryName = $category->name;


    // To get the tournament.
    $tournament = $categoryTournament->tournament;

    // To get the name of the tourament (if there is a name column)
    $tournamentName = $tournament->name;
    $tournament->created_at; // etc...


    // To get all the people participating in this tournament category
    foreach($categoryTournament->users as $user) {
        echo $user->email;
    }
}

If you need to figure out how to traverse the relationships (getting all tournaments and categories a user is participating in, etc...) please feel free to ask.

Starting at the User

// This will list all tournament and category names a user belongs to.
$user = App\User::with('categoryTournaments.tournament', 'categoryTournaments.category')->find($userId);
foreach($user->categoryTournaments as $categoryTournament) {
    echo 'Category Name: '.$categoryTournament->category->name;
    echo 'Tournament Name: '.$categoryTournament->tournament->name;
    echo '<br>';
}

Edit

  • users and category_tournament make a belongsToMany relationship.
  • categories and tournaments make a belongsToMany relationship.
  • category_tournament also has a belongsTo to both tournaments and categories

There is a possibility we can further simplify this if you remove the tables tournaments and categories and drop all their columns right into category_tournament. That way, you end up with only one belongsToMany relationship to manage.

Ad
source: stackoverflow.com
Ad