我正在努力找到能够满足我需求的生成器与原始SQL的正确组合。
我有一个允许用户配置的设置
X
数量
TournamentQuizmasters
需要用于
十、
数量
Teams
.为了提高效率,我需要在MySQL级别上进行此计算
,因此我可以快速查询所有符合条件的团队。我有其他查询范围来确定合格团队是什么(例如。
withEnoughPlayers()
)。
这个代码不起作用,但我认为它传达了我的意图。
// A collection of Teams
class TeamSet extends Model {
public function scopeWithEnoughQuizmastersBasedOnTeamCount(Builder $q, Tournament $tournament)
{
// Pull only the groups that bring enough quizmasters. The required number
// of quizmasters is based off of the number of teams they're bringing.
return $q->whereHas('group', function (Builder $q) use ($tournament) {
$q->has(
'tournamentQuizmasters',
'>=',
DB::raw('FLOOR(('.$tournament->settings->quizmastersToRequireByTeamCount().' * '.$q->selectRaw('COUNT(*)')->teams()->withEnoughPlayers($tournament)->toSql().') / '.$tournament->settings->teamCountToRequireQuizmastersBy().')')
);
});
}
}
运行我得到的查询
Call to undefined method Illuminate\Database\Eloquent\Builder::teams()
我认为这是因为
selectRaw()
继续进行。我也不认为我真的可以打电话
->teams()
我在这里的方式,但我有点盲目,我应该如何改变这一点,以获得我正在寻找的结果。
如何在利用查询生成器的同时执行此动态表达式,以便利用我的作用域?
我用的是Laravel 5.7
型号(&M);关系
class TeamSet {
public function group() : BelongsTo
{
return $this->belongsTo(Group::class);
}
public function teams() : HasMany
{
return $this->hasMany(Team::class)
}
}
class Team {
public function teamSet() : BelongsTo
{
return $this->belongsTo(TeamSet::class)
}
}
class Group {
public function tournamentQuizmasters() : HasMany
{
return $this->hasMany(TournamentQuizmaster::class);
}
public function teams() : HasManyThrough
{
return $this->hasManyThrough(Team::class, TeamSet::class);
}
}
class Tournament {
public function teamSets() : HasMany
{
return $this->hasMany(TeamSet::class);
}
public function teams() : HasManyThrough
{
return $this->hasManyThrough(Team::class, TeamSet::class);
}
}
class TournamentQuizmaster {
public function group() : BelongsTo
{
return $this->belongsTo(Group::class);
}
public function tournament() : BelongsTo
{
return $this->belongsTo(Tournament::class);
}
}
型号说明:
-
TeamSet
-表示团队集合的单个实体。这使我们的用户能够在多场比赛中使用同一组球队。
-
Team
-球员的集合
-
Group
-组名称。这在应用程序中的其他位置使用,但每
团队集合
属于某个组。
-
Tournament
-不言而喻
-
TournamentQuizmaster
-比赛的裁判或裁判。根据团队数量,每组需要带X个
$锦标赛->设置
这作为json存储在数据库中,但转换为对象,因此我有一个合理的位置来保留默认值。下面是该类的一个片段:
use Illuminate\Support\Fluent;
class Settings extends Fluent
{
const DEFAULT_MAXIMUM_PLAYERS_PER_TEAM = 5;
const DEFAULT_MINIMUM_PLAYERS_PER_TEAM = 3;
public function __construct($attributes = [])
{
if ($attributes !== null) {
parent::__construct($attributes);
}
}
public function shouldRequireQuizmasters() : bool
{
return $this->get('requireQuizmasters', 'none') != 'none';
}
public function shouldRequireQuizmastersByGroup() : bool
{
return $this->get('requireQuizmasters', null) == 'group';
}
public function quizmastersToRequireByGroup() : int
{
return $this->get('quizmastersToRequireByGroup', 1);
}
public function setQuizmastersToRequireByGroup(int $quizmasterCount)
{
$this->quizmastersToRequireByGroup = $quizmasterCount;
}
public function shouldRequireQuizmastersByTeamCount() : bool
{
return $this->get('requireQuizmasters', null) == 'team_count';
}
public function quizmastersToRequireByTeamCount() : int
{
return $this->get('quizmastersToRequireByTeamCount', 1);
}
存储在数据库中的json最终看起来像:
{"collectShirtSizes":"1","collectQuizmasterPreferences":"1","allowsGuestPlayers":true,"minimumPlayersPerTeam":3,"maximumPlayersPerTeam":6,"requireQuizmasters":"group","quizmastersToRequireByGroup":1,"quizmastersToRequireByTeamCount":1,"teamCountToRequireQuizmastersBy":2}