【问题标题】:Eloquent query returns wrong data when when using union使用联合时,雄辩的查询返回错误的数据
【发布时间】:2020-01-13 20:47:51
【问题描述】:

我的代码中有公共数据和用户特定数据之间的联合。我想要实现的是,如果没有用户登录,我返回 public 为 true 的数据。如果我有一个用户,我会进行另一个查询,其中 user_id 是登录用户。一切正常,直到我想获得不应该被允许的用户的特定数据 ID。

例如我有数据:

[
   'id' => 1,
   'user_id' => 1,
   'public' => true,
],
[
   'id' => 2,
   'user_id' => 1,
   'public' => false,
],

我当前的代码:

    public function getQuery() : Builder
    {
      $publicData = $this->model->where('public', true);

      // $this->user is passed thought another method which is $request->user() result. 
      if (!isset($this->user)) {
        return $publicData;
      }

      if ($this->user->isAdmin()) {
        return $this->model->newQuery();
      }

      return $this->model
        ->where('user_id', $this->user->id)
        ->union($publicData);
    }

现在我们假设 $this->user->id 为 10,我尝试获取 id 不允许的数据。

    $data = $this->getQuery()
        ->where('id', 2)
        ->first();

在这种情况下,总是会返回第一个公共数据,在这种情况下是 id 1,我希望收到 null。

我不确定如何找到解决方案,也不确定我缺少什么。目前我使用 Laravel 6

【问题讨论】:

    标签: php laravel eloquent


    【解决方案1】:

    您的代码中存在潜在问题,它使用一个查询来进行联合和结果查询。

    你可以试试这个:

    public function getQuery() : Builder
    {
      // HERE ADDED newQuery
      $publicData = $this->model->newQuery()->where('public', true);
    
      // $this->user is passed thought another method which is $request->user() result. 
      if (!isset($this->user)) {
        return $publicData;
      }
    
      if ($this->user->isAdmin()) {
        return $this->model->newQuery();
      }
    
      return $this->model
        ->where('user_id', $this->user->id)
        ->union($publicData);
    }
    

    但您建议简化查询,不要使用联合,因为这里不需要联合,例如:

    public function getQuery() : Builder
    {
      $query = $this->model->newQuery();
    
      if ($this->user->isAdmin()) {
        return $query;
      }
    
      return $query->where(function ($builder) {
        $builder->where('public', true);
    
        if (isset($this->user)) {
           $builder->orWhere('user_id', $this->user->id);
        }
      });
    }
    

    【讨论】:

    • 第二个例子对我的帮助最大,我不够聪明,没有使用联合来思考它。谢谢
    【解决方案2】:

    在 Laravel 中,您通过 auth()->id() 获取登录用户 ID。您似乎正在尝试按 eloquent 的附加用户过滤结果,这显然会为每一行返回 true

    【讨论】:

    • 可能我表达的不对,抱歉。我有一个抽象,但在我的例子中 $this->user 是从 $request->auth() 传递的用户,它与 auth() 相同。
    猜你喜欢
    • 1970-01-01
    • 2016-09-18
    • 2018-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-09
    • 1970-01-01
    • 2021-01-12
    相关资源
    最近更新 更多