develpr
develpr

Reputation: 1406

How do I use an intermediary to connect tables in Laravel?

I have recently started working with Laravel and am looking to really start digging into it and all of its power. I am currently trying to do something fairly simple, pair a player with their corresponding stats. I have 3 classes and corresponding tables in my database:

Player 
Stats 
PlayerStatsLink

The PlayerStatsLink table has a 'player_id' and a 'stats_id' column that connects each player to their corresponding stats. Where I am getting somewhat confused is how to use the belongsTo and hasOne methods in this situation with the link. Right now here is what my classes look like:

Player.php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Player extends Model
{
    public function stats() 
    {

        return $this->hasOne('App\Stats');

    }
}

Stats.php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Stats extends Model
{
    public function players() 
    {

        return $this->belongsTo('App\Player');

    }
}

I am confused as to how to incorporate my link class into the mix, even though I'm pretty sure it is the right thing to do based on what I have learned about databases and structures. I have considered adding a player_id column to the Stats table to make what I have right now work, but I'm not sure if that is the right way to do this.

What I would ideally like to be able to do to access this data after the PlayerStatsLink has connected a player with corresponding stats is something like this:

{{ $player->stats->points }}

Upvotes: 0

Views: 168

Answers (1)

Peyman
Peyman

Reputation: 312

Okay let us assume you have 3 models: User, Stat and GameLog. I suggest you to use singular name for your models to avoid any confusion.

let us start with creating them:

php artisan make:model --migration Stat

to create both Stat model and stats table.

php artisan make:model --migration GameLog

to create both GameLog model and game_logs table.

This is the easiest way to create models and tables and bind them together and avoid typos. User model and corresponding table is present with fresh laravel installation.

in you User model:

public function gameLogs(){
    return $this->hasMany(GameLog::class);
}

public function stats(){
    return $this->hasManyThrough(Stat::class, GameLog::class);
}

in GameLog model:

public function user(){
    return $this->belongsTo(User::class); // each gamelog belongs to just one user
}

public function stat(){
    return $this->hasOne(Stat::class);
}

then in your Stat model:

public function gameLog(){
    return $this->belongsTo(GameLog::class);
}

Please remember to construct you database also. If you faced problem in it please let me know and I will help you with.

Now if you want to query a User gamelogs you simply need to:

$user = User::find(1);
$gamelogs = $user->gameLogs;

since $user has many gamelogs you need to iterate trough them:

foreach(gamelogs as gamelog){
    //do your logic
}

also if you want to load stat relationship of gamelog and use it then please read section eager-loading in laravel documents and learn about that.

I hope the explanation is clear and enough. If not please let me know. But I have a suggestion for a better database structure. I think it is better to merge stats table and game_logs table together and omit the model GameLog or Stat. Practically it is exactly the same.

Upvotes: 2

Related Questions