使用嵌套关系时如何返回单个模型?

时间:2019-11-14 16:53:34

标签: php laravel

我目前正在使用MySQL数据库(v5.7)进行Laravel项目(v6.5.1),该数据库主要用于组织足球比赛。由于现在变得有点复杂,我在查询所有模型时都有些困惑。让我进一步解释,这样更有意义:

结构如下:

每个俱乐部都是独立的。

俱乐部表(ID,名称等)。

每个俱乐部都有多个赛季,现在让我们从第1赛季开始。 季节表(编号,赛季编号,club_id) hasMany与Match表的关系

每个赛季将进行许多比赛。 匹配表格(编号,季节编号和其他一些列) 与团队有很多关系

每次比赛都会有一群注册的玩家。 团队表(id,match_id,user_id和其他一些列)

我需要做的第一件事是,返回俱乐部的当前赛季。我通过以下雄辩的查询来做到这一点:

我转到俱乐部表,使用$ url(从uri传递)查询它,返回匹配的第一个俱乐部,使用Club和Season之间的hasMany关系并返回最新的季节(因为它将始终是当前的)

Club::where('url_extension', $url)->first()->seasons->sortByDesc('season')->first();

现在我拥有当前的Season模型,我将hasMany Matches关系用于Season来返回所有即将到来的Matches:

$season->matches->where('match_date_time','>=', date('Y-m-d hh:ii:ss'));

现在我有一个匹配项。

当我在Matches集合中执行foreach时,我可以访问每个Match Model,然后使用hasMany Team关系(团队通常是一组已报名参加该比赛的玩家),它返回所有选择参加该游戏。

foreach($matches as $match) {
           $players = $match->players;
        }

本质上,从上面的$ players集合(包含所有参加比赛的玩家组成)中,我想知道的每个比赛是,如果该团队中存在已登录用户(例如user_id = 3)是否匹配。这将允许我整理前端,让玩家选择“选择加入”还是“选择退出”游戏。这也将使我阻止用户选择已经注册的游戏。

非常感谢您的帮助。

编辑(归功于Gage LaFleur): 因此,我将代码重构为以下代码。

@if($match->players->contains('user_id', auth()->id()))
<td>
<form method="POST" action="{{ route('match.cancel-availability' , $club->url_extension) }}">
@csrf
@method('DELETE')
<input type="hidden" value="{{ $match->id }}" name="match_id">
<button type="submit" class="btn btn-outline-success">Cancel Availability</button>
</form>
</td>
@else
<td>
<form method="POST" action="{{ route('match.submit-availability' , $club->url_extension) }}">
@csrf
<input type="hidden" value="{{ $match->id }}" name="match_id">
<button type="submit" class="btn btn-outline-success">Submit Availability</button>
</form>
</td>
@endif

这在刀片中是“可接受的”吗?我愿意采用更好的方法,谢谢大家到目前为止的帮助。

此外,我刚刚注意到我实际上需要访问“团队模型”表(本质上是该球员),因为该表包含诸如他们所在的团队,是否已经付款,他们进球的目标等值。 ..

3 个答案:

答案 0 :(得分:2)

我建议在玩家集合中使用<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/> <div class="container"> <div class="row"> <div class="col-3"> <nav id="main-nav"> <ul class="nav"> <li><a href="#a" class="active">Link1</a></li> <li><a href="#b">Link2</a></li> <li><a href="#c">Link3</a></li> <li><a href="#d">Link4</a></li> <li><a href="#e">Link5</a></li> </ul> </nav> </div> <div class="col-9"> <div class="scroll-area" data-spy="scroll" data-target="#main-nav" data-offset="0"> <div id="a">Austria</div> <div id="b">Bolivia</div> <div id="c">Canada</div> <div id="d">Denmark</div> <div id="e">England</div> </div> </div> </div> </div>

contains()

答案 1 :(得分:0)

如果我没有正确理解,使用hasManyThrough关系很容易得到答案。它允许您,如果您有3个表ABC,并且A有许多B,B有许多C,以使C元素连接到A,并且比那些记录中的多,您只能选择id并检查id是否存在在那个集合中

答案 2 :(得分:0)

您能否通过in_array()的foreach检查用户是否在当前匹配项中?

foreach($matches as $match) {
    $players = $match->players;
    if(in_array($players->pluck('user_id', $currentUser)->toArray())){
        //User is in this match
    }else{
        //User is not in this match
    }
}

还有其他一些可能更干净的方法可以解决此问题,但是以上内容可能是最简单的方法。如果您有兴趣,我建议您以另一种方法解决此问题。而是循环播放与俱乐部的深厚关系。

由于我不确定100%是否要检索什么数据,因此我将假设其为:

俱乐部->季节(可能是可变的):

  1. 匹配
    1. 玩家
    2. 玩家
  2. 匹配
    1. 玩家
    2. 玩家
  3. 匹配
  4. 等等。

,您有一个经过身份验证的用户,可以与该树中的Player个模型之一进行匹配。这带有以下限制:用户应该能够看到他们所参与的比赛,注册新比赛的能力以及取消注册已经注册的比赛的能力。