Как использовать несколько whereHas с where в laravel - PullRequest
0 голосов
/ 04 июля 2019

Я использую где с несколькими whereHas (), и я не получаю ожидаемый результат.

Это мой код

public function getCommunityScoreByUser($user,$category_id) {
      $question_ids = $user->answers->pluck('question_id')->unique();

      $specialities = $this->speciality
                    ->whereHas('questions', function($qry) use($question_ids){
                        $qry->whereIn('questions.id', $question_ids);
                       })
                    ->orwhereHas('caseStudies', function($qry) use($user) {
                        $qry->where('user_id', $user->id);
                       })
                    ->where('is_active', 'Y')
                    ->where('category_id',$category_id)
                    ->withCount('answers')
                    ->withCount(['answers as bestAnswerCount' => function ($query) {
                                $query->where('question_answer.is_accepted','Y');
                                }])
                    ->with(['answers' => function ($query) {
                          $query->withCount(['votes' => function ($query) {
                                $query->where('count','1');
                             }]);
                      }])
                    ->get();
      foreach ($specialities as $speciality => $key) {
        $votes_count = 0;
        foreach ($key->answers as $key1 => $value) {
          $votes_count += $value->votes_count;
        }
        $key->votesCount = $votes_count;
        $key->totalVotes = (3*$key->bestAnswerCount)+$votes_count+$key->case_study_votes_count;
      }
      return $specialities;
}  

Ожидаемый результат

Я хочу выбрать специальности, в которых есть вопросы или тематические исследования, и они должны соответствовать критериям ->where('category_id',$category_id)

Фактический результат

$specialities содержит либо вопросы, либо тематические исследования, но это не проверка category_id. Вместо этого он получает $specialities со всеми категориями. Но если я удалю один из объектов whereHas, он будет работать отлично.

Пожалуйста, помогите мне найти решение.

Ответы [ 2 ]

1 голос
/ 04 июля 2019

Использование orWhereHas, вероятно, ведет себя не так, как вы ожидаете. В вашем случае, если

->orwhereHas('caseStudies', function($qry) use($user) {
     $qry->where('user_id', $user->id);
})

верно, тогда это будет разрешено. Не нужно будет проверять все остальные фильтры.

Если вы хотите проверить одну или другую whereHas, вам необходимо добавить их в свои where, чтобы «ограничить» or.

->where(function($query) use ($question_ids, $user){
    $query->whereHas('questions', function($qry) use($question_ids){
        $qry->whereIn('questions.id', $question_ids);
    })
    ->orwhereHas('caseStudies', function($qry) use($user) {
        $qry->where('user_id', $user->id);
    });
})
1 голос
/ 04 июля 2019

Полученный результат обусловлен orWhereHas.С вашим текущим заявлением, он получит все специальности, где у него есть вопросы, ИЛИ, где у него есть тематические исследования, где он активен и т. Д..

Для этого вы можете сделать следующее:

$specialities = $this->speciality
    ->where(function ($qry) use ($question_ids, $user) {
        $qry->whereHas('questions', function ($qry) use ($question_ids) {
            $qry->whereIn('questions.id', $question_ids);
        })->orwhereHas('caseStudies', function ($qry) use ($user) {
            $qry->where('user_id', $user->id);
        });
    })
    ->where('is_active', 'Y')
    ->where('category_id', $category_id)
    ->withCount('answers')
    ->withCount(['answers as bestAnswerCount' => function ($query) {
        $query->where('question_answer.is_accepted', 'Y');
    }])
    ->with(['answers' => function ($query) {
        $query->withCount(['votes' => function ($query) {
            $query->where('count', '1');
        }]);
    }])
    ->get();

Для этого достаточно просто обернуть whereHas в свои собственные, чтобы они обрабатывались независимо.

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