Laravel, где не работает в качестве подзапроса

#mysql #database #laravel

Вопрос:

Здравствуйте, замечательные люди из SO!

У меня есть проблема, которую я не могу решить самостоятельно, даже после поиска, поиска в Интернете и прочтения стольких статей

У меня есть 3 модели:

  1. User
  2. Food
  3. Ingredient
     User.php
    
    public function favourites()
    {    
           return $this->belongsToMany(Food::class, 'food_user', 'user_id', 'food_id', 'id', 'id');
    }`
    
    // Some people dislike some ingredient(s) or alergic to it
    public function dislikes()
    {
           return $this->belongsToMany(Ingredient::class, 'ingredient_user', 'user_id', 'ingredient_id', 'id', 'id');
    }
    
    Food.php
    
    public function likes()
    {
           return $this->belongsToMany(User::class, 'food_user', 'food_id', 'user_id', 'id', 'id');
    }
    
    public function ingredients()
    {
           return $this->belongsToMany(Ingredient::class, 'food_ingredient', 'food_id', 'ingredient_id', 'id', 'id');
    }
    
    Ingredient.php
    
    public function foods()
    {
           return $this->belongsToMany(Food::class, 'food_ingredient', 'ingredient_id', 'food_id', 'id', 'id');
    }
    
    public function disliked()
    {
           return $this->belongsToMany(User::class, 'ingredient_user', 'ingredient_id', 'user_id', 'id', 'id');
     

}

Поэтому, установив эти отношения, теперь я хочу внедрить поисковую систему

 SearchController.php

use ...
use ...

public function foods(Request $request)
{
    $user = User::with(['dislikes'])->find(x);

    $dislikes = $user->dislikes->pluck('pivot')->pluck('ingredient_id')->toArray();

    $query = $request->query('keyword');

    $builder = Food::query()->with(['ingredients']);

    $builder->where('name', 'LIKE', "%$query%");

    $builder->orWhereHas('ingredients', function ($query) use ($dislikes) {
        // This is not working, it STILL fetch all food with ingredients the current user dislikes
        $query->whereNotIn('ingredient_id', $dislikes);
    });

    $foods = $builder->get();

    return ...
}
 

Есть идеи, почему whereNotIn() бы не работать внутри orWhereHas() клаузулы?

Заранее спасибо

Комментарии:

1. dd($не нравится) что вы получаете

2. Идентификаторы нелюбимого ингредиента(ов): [3, 7, 10]

3. Хорошо. позвольте мне еще раз проанализировать ваш запрос.так как он хорошо выглядит

4. попробуй или куда-нибудь, куда

5. просто распечатайте qurey, если он не работает, тогда вы получите некоторое представление о том, какой случай не удался

Ответ №1:

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

 $builder = Food::query()->with(['ingredients'=>function ($query) use ($dislikes) {
     $query->whereNotIn('ingredient_id', $dislikes);
     }]); 
    $builder->where('name', 'LIKE', "%$query%"); 
    $foods = $builder->get(); 
 

вы можете использовать обратный вызов внутри с отношением или вы можете использовать при обратном вызове, как показано ниже

 $builder = Food::query()->when(count($dislikes),function ($q) use ($dislikes){
 $q->whereHas('ingredients',function ($query) use ($dislikes) {
 $query->whereNotIn('ingredient_id', $dislikes);
 }); 
}); 
$builder->where('name', 'LIKE', "%$query%"); 
$foods = $builder->get(); 
 

Комментарии:

1. @ChristianDelvianto.no проблемы .рад, что вы решили свои проблемы

Ответ №2:

Замените orWhereHas на whereHas, так как вы используете whereNotIn

Комментарии:

1. Здравствуйте, спасибо за ответ, но, боюсь, вы опоздали, извините