Красноречивый запрос возвращает неверные данные при использовании объединения - PullRequest
1 голос
/ 13 января 2020

В моем коде есть объединение между данными publi c и данными пользователя c. Чего я хочу добиться, так это того, что если пользователь не вошел в систему, я возвращаю данные, для которых publi c имеет значение true. В случае, если у меня есть пользователь, я делаю другой запрос, где user_id - зарегистрированный пользователь. Все работает до тех пор, пока я не хочу получить указанный c идентификатор пользователя, который мне не разрешен.

Например, у меня есть данные:

[
   '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, и я пытаюсь получить данные, которые не разрешены идентификатором.

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

В этой ситуации всегда будут возвращаться первые опубликованные c данные, в данном случае это id 1, и я ожидаю получить null.

Я не уверен, как найти решение для этого, и я не уверен, что я скучаю В настоящее время я использую Laravel 6

Ответы [ 2 ]

2 голосов
/ 14 января 2020

Потенциальная проблема в вашем коде, он использует один запрос для объединения и запроса результата.

Вы можете попробовать проверить это:

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);
}

Но вы рекомендуете упростить ваш запрос, не используя union, потому что union здесь не нужен, к примеру:

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);
    }
  });
}
1 голос
/ 14 января 2020

В Laravel вы получите идентификатор пользователя, вошедшего в систему, по auth()->id(). Кажется, вы пытаетесь отфильтровать результаты по прикрепленным пользователям, которые, очевидно, вернут true для каждой строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...