Получить все модели, имеющие отношение c - PullRequest
0 голосов
/ 12 января 2020

В моем приложении Laravel я создаю функцию фильтра. Вы можете отфильтровать модель A, выбрав, какие отношения она должна иметь с моделью B. Модель A имеет отношение многие ко многим с моделью B. Так, например, модель A1 имеет отношение с моделью B1, B2, B3, моделью A2 имеет отношение с B2, B3, а модель A3 имеет отношение с моделью B3.

Если вы выберете только B3 в фильтре, должны отобразиться модели A1, A2 и A3. Если вы выбираете B3 и B2, должны отображаться только A1 и A2.

Есть ли способ решить эту проблему и как? Я понятия не имею, понятен ли мой пример, если нет, скажите, пожалуйста.

Я попытался whereHas, выполнив следующее:

$gyms = Gym::whereHas('facilities', function (Builder $query) use ($facilities) {
    $query->whereIn('id', $facilities);
})->get();

Проблема в том, что если я хочу все тренажерные залы со средством 1 и средством 2 показывают тренажерные залы только со средством 1 или средством 2, но мне нужны модели, которые имеют оба.

Тренажерный зал - это модель A из моего примера, а Facility - модель B. $facilities - это массив идентификаторов объекта.

Ответы [ 2 ]

1 голос
/ 12 января 2020

Для того, чтобы в Laravel содержалось предложение "where in", используется метод whereIn () .

$gyms = Gym::whereHas('facilities', function (Builder $query) use ($facilities) {
    $query->whereIn('facilities.id', $facilities);
})->get();

. Вышеприведенное вернет результаты, соответствующие одному или нескольким из id с в массиве. Если вы хотите возвращать только совпадения, которые содержат все идентификаторы в массиве, вы можете указать это с 3-м и 4-м параметрами whereHas():

$gyms = Gym::whereHas('facilities', function (Builder $query) use ($facilities) {
    $query->whereIn('facilities.id', $facilities);
}, '=', count($facilities)) //<-- This bit
    ->get();

В приведенном выше предположении нет дубликатов id в $facilities и что все id существуют в базе данных.

0 голосов
/ 12 января 2020

WhereIn () имеет значение true, если столбец соответствует одному из массивов. Если вам нужно AND logi c (не ИЛИ logi c), используйте normal, где ()

$gyms = Gym::query()
foreach ($facilities as $key => $value) {
    $gyms->whereHas('facilities', function (Builder $query) use ($facilities) {
        $query->where('facilities.id', $value);
    });
}
$gyms = $gyms->get();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...