Search code examples
phplaravelmodels

Multiple "statuses" for many-2-many table relationship in a Laravel Data Model? Best approach?


I am new to Laravel (only been coding a few months). I've created a DB model that connects two tables "Players" and "Teams" via a pivot table.

class Player extends Model
{
    public function teams()
    {
        # With timetsamps() will ensure the pivot table has its created_at/updated_at fields automatically maintained
        return $this->belongsToMany('p4\Team')->withTimestamps();
    }
}


class Team extends Model
{
    public function players()
    {
        return $this->belongsToMany('p4\Player')->withTimestamps();
    }
}

Players can be members of (many) teams, "own" teams, be "recruited" to teams, and be "rejected" from teams. Both Teams and Players can initiate requests for each of these statuses, allowing the other party to confirm/reject. In each case, they should be linked and can only occupy one of the four statuses. What is the best way to link these two tables such that the relationship between any two instances can be given 4 "statuses"?

I need to give the users (whom control teams and players in this open management/recruitment environment), the ability to request/approve classification in each of the "statuses".

It strikes me that the cleanest way to do this would be to use a single pivot table that "assigns" these given statuses to each linked ID pair. I, however, have only seen simpler examples of this concept executed and am as a result unsure as to what the best way to do that is. I would appreciate some guidance here.

Schema::create('player_team', function (Blueprint $table) {

    $table->increments('id');
    $table->timestamps();

    # `book_id` and `tag_id` will be foreign keys, so they have to be unsigned
    #  Note how the field names here correspond to the tables they will connect...
    # `book_id` will reference the `books table` and `tag_id` will reference the `tags` table.
    $table->integer('player_id')->unsigned();
    $table->integer('team_id')->unsigned();

    # Make foreign keys
    $table->foreign('player_id')->references('id')->on('players');
    $table->foreign('team_id')->references('id')->on('teams');
});

*Again, I'm pretty fresh. Apologies if this has an obvious solution I'm just missing.


Solution

  • If I understood you correctly, you can add status column to a pivot table:

    $table->tinyInteger('status')->unsigned();
    

    Don't forget to add withPivot() to relations:

    return $this->belongsToMany('p4\Player')->withPivot('status')->withTimestamps();
    

    You can access this column with pivot and set or unset it by adding an array to attach() and detach() methods:

    $team->players()->attach($playerId, ['status' => 3]);
    

    Read more about it in docs:

    https://laravel.com/docs/5.3/eloquent-relationships#many-to-many https://laravel.com/docs/5.3/eloquent-relationships#inserting-and-updating-related-models