我已经开始使用Laravel开发网站,并且我几乎可以从这里找到的官方文档和答案中找到所有内容。但是有一件事情-尽管我找到了一种方法-但我有一种感觉可以用比我现在正在做的另一种更优化的方式来完成。让我解释一下。
对于我的网站,我有一个名为“玩家”的表格,其中包含有关从足球比赛中提取的某些玩家的数据。假设结构是这样的:
ID(int,主键,A_I)
GameID(整数,唯一)//游戏使用什么
PlayerName
数据(基本上有许多不同的列)
由于我的网站的目的是允许用户对游戏内容进行修改,因此我还有另一个名为“ userplayers”的表格,用于对原始表格上存在的玩家进行修改,或添加新的。结构类似于“玩家”表,但是只添加了一个列,称为userID,用于标识哪个修改属于哪个用户。
ID(int,主键,A_I)
GameID(int,与用户ID唯一)
PlayerName
数据(基本上有许多不同的列)
UserID(int,与GameID一起唯一)
如果我在userplayers表上添加了一个条目,如果该条目具有与玩家表上的任何条目相同的GameID(并且创建该条目的用户已登录),则在运行时它将覆盖玩家的表条目。如果新条目的GameID在原始玩家表上不存在,则将其追加到该表中。
如果用户未登录,那么我只返回玩家表。
通过使用雄辩的laravel模型,我可以轻松地获取用户未登录时的玩家表。但是,我无法找出仅使用核心雄辩就能返回整个数据库+用户创建的内容的有效方法模型功能。
过去(没有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数组,它会立即返回,我认为这不是正确的方法。例如,当我只是搜索玩家表(不使用用户创建的内容)时,返回结果所需的时间比返回包含自定义内容的结果要短得多。
任何想法都将受到高度赞赏。
答案 0 :(得分:0)
因此,在研究了我的问题和可能的解决方案几天后,我想到了这个解决方案。
因此,让我们逐步进行此操作。
我有一个“ 玩家”模型,该模型从“ 玩家”表中获取数据。
我还有一个“ 用户播放器”模型,该模型从“ 用户播放器”表中获取数据。
我必须在这两个模型之间创建一个关系。 “ 玩家”表中的一个条目可能在“ userplayers ”表中具有许多与它们相关的条目。因此,在 Player 模型中,我添加了以下内容:
public function userplayers()
{
return $this->hasMany('App\Userplayer', 'gameid', 'gameid');
}
在 Userplayer 模型中,我添加了以下内容:
public function player()
{
return $this->belongsTo('App\Player', 'gameid', 'gameid');
}
请求数据时,第一步是从“ 玩家”表中删除与“ << strong> userplayers ”表,该表还具有一个限制,即该表每一行中的“ userId”必须是特定的。
这是在我的SearchPlayerController中执行此操作的代码:
$orig_players = \App\Player::whereDoesntHave('userplayers', function ($query) use($user)
{
$query->where('userId', $user);
})->get();
同时,我需要从“ userplayers”表中获取具有我想要的“ 用户ID ”的每一行
$userplayers = \App\Userplayer::where([
['pesid', $search]
])->get();
现在,我只合并两个结果(我不能使用UNION,因为从“ 玩家”表中获取的数据少了一列)。
$players = $orig_players->merge($userplayers)
->sortBy('registeredName')
->take($limit);
一切正常,并且比以前快很多!