использование ‘и где’ в отношении многие ко многим

#php #laravel #eloquent #many-to-many

#php #laravel #красноречивый #многие ко многим

Вопрос:

У меня есть две модели, которые имеют отношение «многие ко многим».

 class User extends Model
{
    function cars()
    {
        return $this->belongsToMany(Car::class);
    }
}

class Car extends Model
{
    function users()
    {
        return $this->belongsToMany(User::class);
    }
}
  

Я хочу получить пользователей, которые использовали определенный набор автомобилей:

 $car_selected = [1, 3, 6];

$users = User::when(count($car_selected) > 0, function ($q) use ($car_selected) {
    $q->whereIn('cars.id', $car_selected);
})
    ->get();
  

Это дает слишком много результатов из-за условия «Где»; то, что я хочу, это «Где и» что-то.

Я пробовал это, но безуспешно.

 $users = User::when(count($car_selected) > 0, function ($q) use ($car_selected) {
    foreach($car_selected as $xx) {
        $q->where( 'cars.id', $xx);
    }
})
    ->get();
  

Как я могу получить всех пользователей, которые имеют отношение к автомобилям 1, 3 и 6?

Ответ №1:

Предоставленный вами код не имеет большого смысла, но, основываясь на вашем объяснении, вы хотите найти пользователя, который имеет отношение к автомобилям 1, 3 и 6. Использование whereIn() дает вам пользователей с отношениями с автомобилями 1, 3 или 6.

Ваша попытка с несколькими where() фильтрами не сработала бы, так как это означало бы поиск одной строки в сводной таблице с несколькими машинами, что, очевидно, было бы невозможно. Вместо этого вам нужно вложить несколько whereHas() фильтров отношений в одну where() группу, например:

 $users = User::where(function ($q) use ($car_selected) {
    foreach ($car_selected as $car) {
        $q->whereHas('cars', function ($query) use ($car) {
            $query->where('car_id', $car);
        });
    }
})
    ->with(['cars' => function ($q) use ($car_selected) {
        $q->whereIn('car_id', $car_selected);
    }])
    ->get();
  

Все это предполагает, что вы правильно настроили свои отношения и таблицы в соответствии со стандартами Laravel.

Демонстрационный код здесь: https://implode.io/anjLGG

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

1. Да, это то, что я хочу .. да, это ответ для моего случая. Спасибо..

2. Извините за это. Я здесь почти новичок .. и я не могу найти способ принять ваш ответ.. Я тоже не вижу ✅. и в качестве ответа есть чей-то неправильный ответ. Я могу сказать, что я не принял этот неправильный код. Я прокомментировал событие, что это неверно. В любом случае извините за то, что причинил какую-то боль .. но не спешите принимать ваши. вот почему я прокомментировал ваш идентификатор и ответ.. Если вы дадите мне знать, как это исправить, я это сделаю. Спасибо.

Ответ №2:

Вы можете использовать whereHas метод для запроса отношения:

 use IlluminateDatabaseEloquentBuilder;

    User::whereHas('cars', function (Builder $builder) use($car_selected)
            {
                $builder->whereIn( 'cars.id', $car_selected);
            })->get();
  

Для получения дополнительной информации проверьте документ

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

1. Спасибо за ответ.. Но теперь это то, чего я хочу. Использование ‘Where’ не может получить пересекающиеся строки. пожалуйста, внимательно прочитайте мой вопрос..

2. итак, что вы подразумеваете под «Это дает комбинацию из-за «условия Where». С какой проблемой вы сталкиваетесь?

Ответ №3:

как объяснил @miken32, мне нужно вложить несколько фильтров отношений whereHas () в одну группу where() .

@miken32 предложил следующее..

 
$users = User::where(function ($q) use ($car_selected) {
    foreach ($car_selected as $car) {
        $q->whereHas('cars', function ($query) use ($car) {
            $query->where('car_id', $car);
        });
    }
})
    ->with(['cars' => function ($q) use ($car_selected) {
        $q->whereIn('car_id', $car_selected);
    }])
    ->get();

  

И я думаю, что следующего достаточно.

 
$users = User::where(function ($q) use ($car_selected) {
    foreach ($car_selected as $car) {
        $q->whereHas('cars', function ($query) use ($car) {
            $query->where('car_id', $car);
        });
    }
})->get();
  

Спасибо.