我已经开始使用 Laravel 开发一个网站,并且我几乎通过我在这里找到的官方文档和答案找到了所有内容。然而,有一件事 - 尽管我已经找到了一种方法 - 我有一种感觉可以用另一种比我现在正在做的更优化的方式来完成。让我解释一下。
对于我的网站,我有一个名为“球员”的表,其中包含从足球比赛中提取的一些球员的数据。假设结构如下:
<小时/>ID(int,主键,A_I)
GameID (int, unique)//游戏使用的内容
玩家姓名
数据(基本上是许多不同的列)
<小时/>由于我网站的目的是允许用户对游戏内容进行修改,所以我还有另一个表,我称之为“userplayers”,我用它来对原始表上存在的玩家进行修改,或添加新的。其结构类似于“players”表,但只添加了一列,称为 userID,用于标识哪个修改属于哪个用户。
<小时/>ID(int,主键,A_I)
GameID(int,与userID一起唯一)
玩家姓名
数据(基本上是许多不同的列)
UserID(int,与GameID一起唯一)
<小时/>如果我在 userplayers 表上添加一个条目,如果该条目与玩家表上的任何条目具有相同的 GameID(并且创建它的用户已登录),那么在运行时它会覆盖玩家表条目。如果新条目的 GameID 不存在于原始玩家表中,则它会被附加到其中。
如果用户未登录,那么我只返回玩家表。
通过使用 eloquent laravel 模型,我可以在用户未登录时轻松检索玩家表。但是,我无法找到一种仅使用核心 eloquent 返回整个数据库 + 用户创建的内容的有效方法模型函数。
过去(没有 Laravel)我使用这个数据库查询:
SELECT * FROM (SELECT *, NULL FROM players WHERE NOT EXISTS (SELECT * FROM userplayers WHERE players.gameid=userplayers.gameid AND userId=$userId) UNION (SELECT * FROM userplayers WHERE userId=$userId)) AS pl;
我“发现”在 Laravel 中执行此类操作的方法是在 Players 模型中添加本地范围,如下所示:
public function scopeIncludeCustom($query, $user)
{
return \DB::select('SELECT * FROM (SELECT *, NULL FROM players WHERE NOT EXISTS (SELECT * FROM userplayers WHERE userplayers.gameid=players.gameid AND userId='.$user.') UNION (SELECT * FROM userplayers WHERE userId='.$user.')) AS players_full);
}
但是您可以理解,这不会按范围返回 $query,而只是返回一个 php 数组,我认为这不是执行此操作的正确方法。例如,当我只是搜索玩家表(不使用用户创建的内容)时,返回结果所需的时间比使用自定义内容返回结果要短得多。
任何想法都将受到极大的赞赏。
最佳答案
因此,经过几天的研究我的问题和可能的解决方案,我想出了这个解决方案。
所以,让我们一步一步来。
<小时/>我有一个“玩家”模型,它从“玩家”表中获取数据。
我还有一个“Userplayer”模型,它从“userplayers”表中获取数据。
<小时/>我必须在这两个模型之间创建关系。 “players”表中的条目可能在“userplayers”表中具有许多与其相关的条目。因此,在玩家模型中我添加了以下内容:
public function userplayers()
{
return $this->hasMany('App\Userplayer', 'gameid', 'gameid');
}
在Userplayer模型中,我添加了以下内容:
public function player()
{
return $this->belongsTo('App\Player', 'gameid', 'gameid');
}
<小时/>
请求数据时,第一步是从“players”表中删除与“players”表中返回的任何行具有相同“GameId”的每一行。
这是在我的 SearchPlayerController 中执行此操作的代码:
$orig_players = \App\Player::whereDoesntHave('userplayers', function ($query) use($user)
{
$query->where('userId', $user);
})->get();
同时,我需要从“userplayers”表中获取具有我想要的“userid”的每一行
$userplayers = \App\Userplayer::where([
['pesid', $search]
])->get();
现在,我只需合并 2 个结果(我无法使用 UNION,因为我从“players”表中获取的数据少了一列)。
$players = $orig_players->merge($userplayers)
->sortBy('registeredName')
->take($limit);
一切都运行得很好,而且比以前快得多!
关于php - 在 Laravel Eloquent 模型中使用特殊的 union 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52985307/