你能从查询生成器中删除一个子句吗?

Can you remove a clause from the query builder?

查看 API for Builder 似乎查询的所有部分都保存在 $joins, $wheres, $groups 等属性中。 我还看到这些属性是 public.

我的用例是例如范围,比方说(纯小说)

class User extends Model
{
    public function scopeIsSmart($query)
    {
        return $query->join('tests', 'users.id', '=', 'tests.user')
            ->where('tests.score', '>', 130);
    }

    public function scopeIsMathGuy($query)
    {
        return $query->join('tests', 'users.id', '=', 'tests.user')
           ->where('tests.type', '=', 'math');
    }    
}

如果我现在写

User::query()->isSmart()->isMathGuy()->get();

加入同一个 table 两次会出错。使连接数组唯一的好方法是什么? (无重复连接)

试试这个:

$query = Test::query();
   if ($request['is_smart']) {
      $query->where('score', '>', 130);
   }

   if ($request['is_math']) {
      $query->where('type', 'math');
   }
$result = $query->with('users')->all();
$users = $result->get('users');

您可以检查现有的 JOIN:

public function scopeIsMathGuy($query)
{
    if (collect($query->getQuery()->joins)->where('table', 'tests')->isEmpty()) {
        $query->join('tests', 'users.id', '=', 'tests.user');
    }
    $query->where('tests.type', '=', 'math');
}

您还可以创建像 joinOnce() 这样的助手(请参阅此 PR)。