首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >优雅地退出Laravel作用域

优雅地退出Laravel作用域
EN

Stack Overflow用户
提问于 2020-07-21 16:58:08
回答 2查看 36关注 0票数 2

我有一个作用域,它的作用方式取决于用户角色,您可以将一组规则转发到限制来自数据库的最终输出的作用域。

一个非常简单的角色限制示例:

代码语言:javascript
复制
{
    "first_name": "=foo%"
}

将只返回其first_namefoo%开头的记录,这实际上意味着我已禁止具有该角色的用户查看任何不以foo%开头的记录。

这种方法的问题是,如果一个人没有被强加的限制,他将看到一切。我知道这是一个合理的假设,但如果没有限制,我想禁止任何事情,这样如果创建了新角色,它就没有任何权利。

目前,我为这种情况抛出了一个异常:

代码语言:javascript
复制
public function apply(Builder $builder, Model $model)
{
    $input = $this->getAuthValues(get_class($model));

    if (count($input) < 1) {
        throw new \Exception('No rights for you');
    }

    $jsonQuery = new JsonQuery($builder, $input); <-- class responsible for assembling the queries based on the input
    $jsonQuery->search();
}

但这当然也不例外。在这种情况下,我希望返回空数组。

我是否可以使用一些方法来优雅地退出作用域,同时返回一个空结果,而不需要在之后实际执行查询?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-07-21 17:35:03

我找到了一个解决方案来进行不可能的查询,该查询将返回0结果。

代码语言:javascript
复制
public function apply(Builder $builder, Model $model)
{
    $input = $this->getAuthValues(get_class($model));

    if (count($input) < 1) {
        $builder->whereRaw('1 = 0');
        return;
    }

    $jsonQuery = new JsonQuery($builder, $input);
    $jsonQuery->search();
}
票数 1
EN

Stack Overflow用户

发布于 2020-07-21 17:17:43

因为作用域通常是链式的(流畅地调用),并且作用域并不直接负责执行查询,所以我不认为您可以“优雅地退出”,因为下一次调用仍然需要一个Builder对象来处理。

一种可能的解决方案(并不简单)是创建一个扩展Builder类的类,并覆盖所有负责实际从DB获取结果的方法。我不确定您需要重写的所有方法才能在所有情况下无错误地工作。您可能还希望处理AbortedBuilder中的一些插入和更新情况。

代码语言:javascript
复制
class AbortedBuilder extends Builder
{
    ...

    /**
     * Run the query as a "select" statement against the connection.
     *
     * @return array
     */
    protected function runSelect()
    {
        return [];
    }
    
    ...

    /**
     * Run a pagination count query.
     *
     * @param  array  $columns
     * @return array
     */
    protected function runPaginationCountQuery($columns = ['*'])
    {
        return [];        
    }

    ...

    /**
     * Insert a new record and get the value of the primary key.
     *
     * @param  array  $values
     * @param  string|null  $sequence
     * @return int
     */
    public function insertGetId(array $values, $sequence = null)
    {
        throw new \Exception('You are trying to insert using an aborted query!');
    }

    ...
}

然后,在您的范围内,您可以执行以下操作:

代码语言:javascript
复制
public function apply(Builder $builder, Model $model)
{
    $input = $this->getAuthValues(get_class($model));

    if (count($input) < 1) {
        $builder = new AbortedBuilder();
    } else {
        $jsonQuery = new JsonQuery($builder, $input);
        $jsonQuery->search();
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63010974

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档