jeudi 29 novembre 2018

Access pivot table value via a model which relates to both pivoted models

Say I have a table of matches for a game where the opponents score is kept per match, and the match can have any number of players, currently the relationship looks like this:

class Match extends Model {
    public function players() {
        return $this->belongsToMany(Player::class)->withPivot(['score']);
    }
}

class Player extends Model {
    public function matches() {
        return $this->belongsToMany(Match::class)->withPivot(['score']);
    }
}

It works nicely, I can get players of a match and get each players score for that match via the pivot table. I assume I'm doing this much right.

Then we introduce a third model, which easily relates to both models and keeps track of which player spectators of the game place bets on:

class Bet extends Model {
    // get the match the bet is for
    public function match() {
        return $this->belongsTo(Match::class);
    }

    // get the player the bet is for
    public function player() {
        return $this->belongsTo(Player::class);
    }
}

But then we decide we want show a list of bets and the final score the player on the match had relating to that bet, e.g. $bet->playerWithMatch->pivot->score. But obviously, Bet isn't related to Player via a pivot, however it shares both the relationships that the pivot exists to bring together, so the information is already all there to attach it to the pivot table directly.

Sure, one could simply get the related match, then iterate through the players of that match, e.g.:

foreach ($bet->match->players as $player) {
    if ($player->id == $bet->player->id) {
        // yay, we got it!
        return $player->pivot->score;
    }
}
// this should never happen... oh but wait, isn't this a sign of bad design patterns or something?
// should we not find a way to more Eloquently represent all of this? hmm...
return null;

But I would prefer a simpler more "inline" way I can do straight in the initial query and have it available in a Blade template for example and I feel like there must be some way to do this that I'm missing? Without doing an excessive number of queries and/or breaking my ability to use Laravel's pagination?



from Newest questions tagged laravel-5 - Stack Overflow https://ift.tt/2FQNykl
via IFTTT

Aucun commentaire:

Enregistrer un commentaire