【发布时间】:2019-03-29 19:57:54
【问题描述】:
我已经开始使用 Laravel 开发一个网站,我几乎可以通过我在这里找到的官方文档和答案找到所有内容。然而,有一件事——即使我找到了一种方法——我有一种感觉,可以用另一种比我现在做的更优化的方式来完成。让我解释一下。
对于我的网站,我有一个名为“球员”的表格,其中包含从足球比赛中提取的一些球员的数据。假设结构是这样的:
ID(整数,主键,A_I)
GameID (int, unique) //游戏使用什么
玩家姓名
数据(基本上很多不同的列)
由于我的网站的目的是允许用户对游戏内容进行修改,我还有另一个表,我称之为“userplayers”,用于对原始表中存在的玩家进行修改,或添加新的。该结构类似于“玩家”表,但只添加了一个名为 userID 的列,用于标识哪个修改属于哪个用户。
ID(整数,主键,A_I)
GameID(整数,与用户 ID 一起唯一)
玩家姓名
数据(基本上很多不同的列)
UserID(整数,与 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 数组,我认为这不是正确的方法。例如,当我只搜索玩家表时(不使用用户创建的内容),返回结果所需的时间比返回自定义内容的结果要短得多。
非常感谢任何想法。
【问题讨论】:
-
已经定义了
Player和UserPlayer模型?你熟悉 Eloquent 关系和whereHas()吗? -
@JonasStaudenmeir 是的,我已经定义了这两个模型,但我似乎不明白如何通过
whereHas()等关系来表示上述 mysql 语法 -
你可以在 Eloquent 中使用
UNION查询,但结果都是Player模型的实例:如果你想要Player和UserPlayer实例,你必须执行单独的查询。
标签: php mysql laravel model eloquent