【问题标题】:Relation between 3 tables in Laravel 5.7Laravel 5.7中3个表之间的关系
【发布时间】:2019-01-24 00:32:53
【问题描述】:

我有三张桌子:

PLAYERS with a team_id

TEAMS

SCORES with a player_id 

事情是这样的:

我的球队有得分的球员,我想对球队进行排名。因此,如果一支球队有几名球员,则基本上是按球员获得最好的成绩,然后将其相加。

例如:

团队 A 有球员 1 和球员 2。 玩家 1 有 3 个分数(例如 300、150 和 500),我想只保留最好的一个(所以 500)。

你知道我该怎么做吗? 由于球队与分数之间或球员与分数之间没有直接关系,我不明白如何在这三者之间建立联系。

感谢您的帮助!

编辑

评分模型

class Score extends Model
{
protected $fillable = [
    'value', 'player_id'
];

public function player()
{
    return $this->belongsTo('App\Player');
}

public function players_scores()
{
    return $this->hasManyThrough('App\Team', 'App\Player');
}

}

玩家模型

class Player extends Model
{
protected $fillable = [
  'name','email','team_id'
];

/**
 * Get the team of the player
 */
public function team()
{
    return $this->belongsTo('App\Team');
}

/**
 * Get the scores of the player
 *
 * @return \Illuminate\Database\Eloquent\Relations\HasMany
 */
public function scores()
{
    return $this->hasMany('App\Score');
}

/**
 * Get the maximum score from the player
 *
 * @return mixed
 */
public function getBestScoreAttribute()
{
    return $this->scores->max('value');
}


}

团队模式

class Team extends Model
{
protected $fillable = ['name','logo'];

protected $appends = ['score'];

public function players()
{
    return $this->hasMany('App\Player');
}

/*
 * Collect all the team players scores
 */
public function players_scores()
{
    return $this->hasManyThrough('App\Score', 'App\Player');
}

public function scores()
{
    return $this->hasMany('App\Score');
}

/*
 * Sum the score of all team players to get the team score
 */
public function getScoreAttribute()
{
    return $this->players_scores->sum('value');
}   

}

【问题讨论】:

  • 所以你想得到一个团队中所有球员的最好成绩,将它们相加并将其存储在特定团队下。对吗?
  • 没错! :)

标签: laravel relationship


【解决方案1】:

首先,您应该在 Player 模型上定义一个 hasMany 函数,指向 Score 模型。然后你可以通过$player->scores()->max('value')查询Player的最佳分数(假设$value是Score模型中保存实际分数值的属性)。

一旦你有了它,你就可以使用那个 sn-p 来定义an accessor,这样你就可以做类似$player->bestScore 的事情来获得玩家的最高分。

然后有办法查询玩家的最佳分数,你应该在Team 模型上定义一个HasMany 关系,指向Player 模型。获取团队分数的查询类似于$team->players->sum('max_score')。你也可以为这个属性定义一个mutator,这样你就可以像$team->score一样访问这个sn-p。

最后,对所有团队进行排序:

  return Team::all()->sortByDesc('score');

【讨论】:

  • 我已经在 Player 模型上有一个 hasMany 函数。我应该在哪里定义访问器?关于团队模式?我有点迷路了:(但感谢您的帮助!(我在帖子中添加了模型)
【解决方案2】:

试试这个简单的方法

首先选择一个特定球队的所有球员,比如

$players=PLAYERS::where('team_id',1)->get();//1 is a sample value pass your team_id

然后用foreach迭代每个玩家id,得到最高分

foreach($players as $player)
{
   $score=SCORES::where('player_id',$player)->orderBy('score', 'desc')->value('score'); // gets only the highest score of the player
   $total=$total+$score;//Sum of the highest score
}

那么如果你想插入到表中意味着

TEAMS::create(['team_id'=>1,'score'=>$total]);

希望对你有帮助:)

【讨论】:

  • 我试过了,但它不起作用:(但感谢您的帮助!
【解决方案3】:

如果有人遇到同样的问题,我找到了解决方案:

static function getDailyTeams(int $limit = 10)
{        
    $callback = function($query) {
        $query->whereDate('scores.created_at', date('Y-m-d'));
    };
    $player = function($query) use ($callback) {
        $query->whereHas('scores', $callback)->with(['scores' => $callback]);
    };
    $teams = Team::with(['players' => $player])->get()->sortByDesc(function ($team) {
        return $team->players->sum('best_score');
    }
    );
    return $teams;  
}

【讨论】:

    猜你喜欢
    • 2016-09-03
    • 2018-03-08
    • 2019-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-17
    • 1970-01-01
    相关资源
    最近更新 更多