laravel 5.6 - 为预加载设置正确的关系

laravel 5.6 - setting correct relationships to eager load

设置游戏站点。我有 3 tables。一个用户、军衔(想想军事级别)和一个 rank_history table。

Rank:
id, name, abbr, level, nextlevel, mintime


RankHistory:
id, user_id, rank_id, promoter, reason, created_at

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

public function PromotedBy()
{
    return $this->belongsToMany(User::class, 'rank_history', 'id', 'promoter');
}

public function Rank()
{
    return $this->belongstoMany(Rank::class);
}


user:
id, name, yadda (standard user stuff; nothing relevant)

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

我使用排名历史作为设置晋升、降级和历史记录的一种方式。最终我希望能够输入 $user->rank_detail($detail) 并让它 return 等级的缩写,名称,级别,等等。

user.php

protected $with = ['rankhistory'];

public function rank_detail($detail)
{
    $rankId = $this->RankHistory->pluck('rank_id')->last();

    if (!$rankId) { $rankId = 1;}

    return Rank::where('id', $rankId)->value($detail);
}

这行得通,但它会进行单独的查询调用以命中排名 table 以获取详细信息。因为它非常安全,所以当我获得用户时,我会非常需要排名信息,所以我急切地加载这些信息就足够了。问题是,如何?我试过 hasmanythroughhasmany,甚至尝试添加 $with =[ rankhistory.rank'] 都没有用。我也知道这可以通过向用户 table 添加排名列来解决,但是如果用户可能会经常更改排名,我希望让用户 table 尽可能保持干净。加上历史 table 给用户一个记录。

所以,问题是:我需要向用户(和/或其他文件)添加什么才能急切加载用户的排名信息?

另外值得注意的是,排名历史中的发起人 table 是 FK 以识别用户 table。我将如何获得这种关系?现在我可以 return $history->promoter 它会给我一个 ID.. 我怎样才能在没有不必要的查询调用的情况下获取用户信息?

试试这个:

class User
{
    protected $with = ['rankHistory.rank'];

    public function rankHistory()
    {
        return $this->hasOne(RankHistory::class)->latest();
    }

    public function rank_detail($detail)
    {
        if ($this->rankHistory) {
            return $this->rankHistory->rank->$detail;
        }            

        return Rank::find(1)->$detail;
    }
}

class RankHistory
{
    public function rank()
    {
        return $this->belongsTo(Rank::class);
    }
}